home *** CD-ROM | disk | FTP | other *** search
- /*
- File: RlShell.cpp
-
- Contains: Shell implementation
-
- Owned by: Nick Pilch
-
- Copyright: © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <39> 8/13/96 DM 1362809,1376080: reset fatal container
- error flags to false and call handler with
- false to disallow suppression
- <38> 7/30/96 eeh 1372943: test for kTranslateItem and -108
- <37> 7/28/96 DH If there are any errors in OpenFile
- attempting to open the draft, we will
- immediately exit the process. Temporary
- low-memory fix.
- <36> 7/24/96 NP 1369891: Send quit event to ourselves in
- response to the quit menu command.
- <35> 19.07.1996 NP 1370120: don't call ExceptionAlert when
- InitODSession fails. Just go away.
- <34> 7/11/96 TJ Fixed Removing of UnsavedNewDocument from
- Stationary
- <33> 7/11/96 TJ Fixed Name of function to check for MacOS 8
- <32> 6/27/96 TJ 1334727 Truning stationery into document
- can cause it to disappeare! is now realy
- fixed.
- <31> 6/23/96 NP 1323565: Refuse to run under MacOS 8.
- <30> 6/22/96 TJ 1334727 Truning stationery into document
- can cause it to disappeare!
- <29> 6/21/96 jpa 1358818: Use "File" menu title in CyberDog.
- 1358820: Open "New" doc in same process in
- CD. 1341242: (CL) Shouldn't be able to
- activate windows w/modal dialog up
- <28> 6/20/96 JP 1339269: Made quit handle the saving
- parameter too
- <27> 6/19/96 jpa 1357406: Call MMOverridePlatform in
- Initialize method.
- <26> 6/18/96 NP 1330731: Default stationery checkbox to
- setting of Document Info.
- <25> 6/14/96 eeh 1322456: check all frags in container
- <24> 6/12/96 eeh 1315197: call parts' adjustMenus when F-key
- pressed
- <23> 6/7/96 eeh T10017: function ptrs must be extern C
- <22> 6/7/96 eeh T10017: return CFM errors
- <21> 6/7/96 eeh T10017: call Dialogs lib instead of
- DraftsWindow
- <20> 6/5/96 EL 1355529: Use InitKindsPopUp in InfoUtil so
- it don't need to be duplicated.
- <19> .06.1996 NP 10002: Launch time fixes, system process.
- <18> 5/31/96 jpa T10012: CyberDog process model (changes to
- OpenFile, etc.)
- <17> 5/24/96 JA 1246074: Native exception compatibility.
- <16> .05.1996 NP 1352438: Factor IsOptionKeyDown and
- IsAnyKeyDown
- <15> 5/8/96 NP 1282265: saving as stationery looks like
- document
- <14> 5/1/96 JA 1213332: Force 68K struct alignment of
- 'cfrg'. Init MW profiler.
- <13> .04.1996 NP 1286751: Present alert when trying to use
- Open… when no Finder is running.
- <12> 4/4/96 NP 1338241: If shell is in infinite loop,
- quit.
- <11> 4/2/96 RA 1320667: Call
- Activate/DeactivateFrontWindows around
- ShowAboutScreen modal dialog call
- <10> 3/29/96 DM 1334273: propagate fatal Bento errors and
- show low mem alert and quit when
- out-of-memory err occurs while trying to
- show low memory alert (solving infinite
- loop).
- <9> 3/22/96 CC 1307182: UpdateMenus: Check for null edit
- menu.
- <8> .03.1996 NP 1307182: Stuff for caching shell menu
- items.
- <7> 3/20/96 EL 1331460 Save a Copy does not include the
- resources in parent document (e.g.
- preferred memory size)
- <6> 3/14/96 NP 1287354: Hide invisible files in the Open
- Document dialog.
- <5> .03.1996 NP 1223399: Don't show error dialog while
- suspending.
- <4> .03.1996 NP 1304875,1317218: Fix can't-cancel problem
- on receipt of quit event.
- <3> 3/1/96 JP 1314798: Made new documents run from temp
- file
- <2> 1/4/96 eeh 1302569: handle fat plugins
-
- In Progress:
-
- */
- #define _USE_DIALOGS_LIB_
-
- #ifndef _PLFMDEF_
- #include <PlfmDef.h>
- #endif
-
- #ifndef _SHELLDEF_
- #include "ShellDef.h"
- #endif
-
- #ifndef _SHLMAIN_
- #include "ShlMain.h"
- #endif
-
- #ifndef _DOCUTILS_
- #include "DocUtils.h"
- #endif
-
- #ifndef _UTILDEFS_
- #include "UtilDefs.h"
- #endif
-
- #ifndef _RLSHELL_
- #include "RlShell.h"
- #endif
-
- #ifndef _SHPLUGIN_
- #include "ShPlugIn.h"
- #endif
-
- #ifndef _BENTODEF_
- #include "BentoDef.h"
- #endif
-
- #ifndef _USERSRCM_
- #include <UseRsrcM.h>
- #endif
-
- #ifndef _EXCEPT_
- #include <Except.h>
- #endif
-
- #ifndef SOM_Module_OpenDoc_Commands_defined
- #include <CmdDefs.xh>
- #endif
-
- #ifndef _ODUTILS_
- #include <ODUtils.h>
- #endif
-
- #ifndef _BINDNGH_
- #include <BindngH.h>
- #endif
-
- #ifndef _BNDNSUTL_
- #include <BndNSUtl.h>
- #endif
-
- #ifndef _TEMPOBJ_
- #include "TempObj.h"
- #endif
-
- #ifndef _TEMPITER_
- #include "TempIter.h"
- #endif
-
- #ifndef _ODMEMORY_
- #include <ODMemory.h>
- #endif
-
- #ifndef _BARRAY_
- #include <BArray.h>
- #endif
-
- #ifndef SOM_ODDispatcher_xh
- #include <Disptch.xh>
- #endif
-
- #ifndef SOM_ODWindowState_xh
- #include <WinStat.xh>
- #endif
-
- #ifndef SOM_ODWindowIterator_xh
- #include <WinIter.xh>
- #endif
-
- #ifndef SOM_ODWindow_xh
- #include <Window.xh>
- #endif
-
- #ifndef SOM_ODMenuBar_xh
- #include <MenuBar.xh>
- #endif
-
- #ifndef _ORDCOLL_
- #include "OrdColl.h"
- #endif
-
- #ifndef SOM_ODFrame_xh
- #include <Frame.xh>
- #endif
-
- #ifndef SOM_ODFrameFacetIterator_xh
- #include <FrFaItr.xh>
- #endif
-
- #ifndef SOM_Module_Apple_defined
- #include <Part.xh>
- #endif
-
- #ifndef SOM_ODArbitrator_xh
- #include <Arbitrat.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_Foci_defined
- #include "Foci.xh"
- #endif
-
- #ifndef SOM_ODSession_xh
- #include <ODSessn.xh>
- #endif
-
- #ifndef SOM_ODLinkManager_xh
- #include <LinkMgr.xh>
- #endif
-
- #ifndef SOM_ODStorageSystem_xh
- #include <ODStor.xh>
- #endif
-
- #ifndef SOM_ODStorageUnit_xh
- #include <StorageU.xh>
- #endif
-
- #ifndef SOM_ODDocument_xh
- #include <Document.xh>
- #endif
-
- #ifndef SOM_ODContainer_xh
- #include <ODCtr.xh>
- #endif
-
- #ifndef SOM_ODClipboard_xh
- #include <Clipbd.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdTypes_defined
- #include <StdTypes.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdProps_defined
- #include <StdProps.xh>
- #endif
-
- #ifndef _ITEXT_
- #include <IText.h>
- #endif
-
- #ifndef _ISOSTR_
- #include <ISOStr.h>
- #endif
-
- #ifndef _PASCLSTR_
- #include <PasclStr.h>
- #endif
-
- #ifndef _STORUTIL_
- #include <StorUtil.h>
- #endif
-
- #ifndef SOM_ODUndo_xh
- #include <Undo.xh>
- #endif
-
- #ifndef SOM_ODInfo_xh
- #include <Info.xh>
- #endif
-
- #ifndef _USE_DIALOGS_LIB_
- #ifndef _DRAFTWN_
- #include "DraftWn.h"
- #endif
- #endif
-
- #ifndef _ODPRCS_
- #include "ODPrcs.h"
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdDefs_defined
- #include <StdDefs.xh>
- #endif
-
- #ifndef _INFOUTIL_
- #include <InfoUtil.h>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StandardExtensions_defined
- #include <StdExts.xh>
- #endif
-
- #ifndef _STDTYPIO_
- #include <StdTypIO.h>
- #endif
-
- #ifndef _DLOGUTIL_
- #include <DlogUtil.h>
- #endif
-
- #ifndef _MEMMGR_
- #include <MemMgr.h>
- #endif
-
- #if ODDebug
- #ifndef _MEMDEBG_
- #include <MemDebg.h>
- #endif
- #endif
-
- #ifndef __QUICKDRAW__
- #include <QuickDraw.h>
- #endif
-
- #ifndef __STANDARDFILE__
- #include <StandardFile.h>
- #endif
-
- #ifndef __FOLDERS__
- #include <Folders.h>
- #endif
-
- #ifndef __FONTS__
- #include <Fonts.h>
- #endif
-
- #ifndef __MENUS__
- #include <Menus.h>
- #endif
-
- #ifndef __OSEVENTS__
- #include <OSEvents.h>
- #endif
-
- #ifndef __DIALOGS__
- #include <Dialogs.h>
- #endif
-
- #ifndef __PACKAGES__
- #include <Packages.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __DESK__
- #include <Desk.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __LOWMEM__
- #include <LowMem.h>
- #endif
-
- #ifndef __GESTALTEQU__
- #include <GestaltEqu.h>
- #endif
-
- #ifndef __SCRIPT__
- #include <Script.h>
- #endif
-
- #ifndef __FINDER__
- #include <Finder.h>
- #endif
-
- #ifndef __FILES__
- #include <Files.h>
- #endif
-
- #ifndef __ICONS__
- #include <Icons.h>
- #endif
-
- #ifndef __ALIASES__
- #include <Aliases.h>
- #endif
-
- #ifndef __TEXTSERVICES__
- #include <TextServices.h>
- #endif
-
- #ifndef __LIMITS__
- #include <limits.h>
- #endif
-
- #ifndef __STRING__
- #include <string.h>
- #endif
-
- #ifndef SOM_ODPartWrapper_xh
- #include "PartWrap.xh"
- #endif
-
- #ifndef __STDIO__
- #include <stdio.h>
- #endif
-
- #ifndef __SEGLOAD__
- #include "SegLoad.h"
- #endif
-
- #ifndef _ODDEBUG_
- #include "ODDebug.h"
- #endif
-
- #ifndef _MEMMGR_
- #include "MemMgr.h"
- #endif
-
- #ifndef _MEMDEBG_
- #include "MemDebg.h"
- #endif
-
- #ifndef _STORUTIL_
- #include <StorUtil.h>
- #endif
-
- #ifndef _NMSPCUTL_
- #include <NmSpcUtl.h>
- #endif
-
- #ifndef SOM_ODBinding_xh
- #include <ODBindng.xh>
- #endif
-
- #ifndef SOM_ODTranslation_xh
- #include <Translt.xh>
- #endif
-
- #ifndef SOM_ODTypeList_xh
- #include <TypeList.xh>
- #endif
-
- #ifndef SOM_ODTypeListIterator_xh
- #include <TypLsItr.xh>
- #endif
-
- #ifndef _SIHELPER_
- #include <SIHelper.h>
- #endif
-
- #ifndef _EDITRSET_
- #include <EditrSet.h>
- #endif
-
- #ifndef _TRANSUTL_
- #include <TransUtl.h>
- #endif
-
- #ifndef _CRAWL_
- #include <Crawl.h>
- #endif
-
- #ifndef _SEUTILS_
- #include "SEUtils.h"
- #endif
-
- #ifndef __EDITIONS__
- #include <Editions.h>
- #endif
-
- #ifndef __CODEFRAGMENTS__
- #include <CodeFragments.h>
- #endif
-
- #ifndef _CONSTDEF_
- #include <ConstDef.h>
- #endif
-
- #ifndef _SHELLMEM_
- #include <ShellMem.h>
- #endif
-
- #ifndef _ERRUTILS_
- #include <ErrUtils.h>
- #endif
-
- #ifndef _ODXDPFNS_
- #include <ODXDpFns.h>
- #endif
-
- #ifdef __MWERKS__
- #if __option(profile)
- #include <profiler.h>
- #endif
- #endif
-
- #pragma segment RealShell
-
- #if ODDebug
- //==============================================================================
- // Debugging #Defines
- //==============================================================================
-
- #endif
-
- //==============================================================================
- // Constants
- //==============================================================================
-
- // <eeh> this should be defined elsewhere, so that parts like EditorSetup can
- // use it rather than risk choosing another constant.
- const ODMenuID kODAppleMenuID = 255;
- const ODMenuID kODDocumentMenuID = 256;
- const ODMenuID kODEditMenuID = 257;
- const ODOSType kODDASMenuRsrc = 0x44525652; // 'DRVR';
-
- const ODSLong kMaxTimeBetweenLocationChecks = 3 * 60L; // Background file check delay
-
- const short kMaxUniqueNameTries = 100;
-
-
- const ODSShort kUseSpecificScript = 0x1c;
-
- #define kMaxNumberSuffixLength 11
-
- // For window resizing
- #define kMinWindowWidth 192
- #define kMinWindowHeight 64
- #define kMaxWindowWidth 16384
- #define kMaxWindowHeight 16384
-
- // from DrawDef.h
- #define kODKindTestDraw "Apple:Kind:TestDraw"
-
- // Local error codes:
-
- #define kODErrClosingNonODWindow 5001
-
-
- #define ODDebugMenu ODDebug /* Use Debug menu if debug build */
-
-
- #if ODDebugMenu
- const ODMenuID kDebugMenuID = 100;
- // Command IDs for the debugging menu:
- enum {
- kODCommandDBHeapInfo = 980,
- kODCommandDBDumpObjects,
- kODCommandDBDumpBlocks,
- kODCommandDBMemValidation,
- kODCommandDBHeapChecking,
- kODCommandDBLeakChecking,
- kODCommandDBDumpBlocksOnClose,
- kODCommandDBTrackStackCrawls,
- kODCommandDBLogStdout,
- kODCommandDBLogDebugWindow,
- kODCommandDBLogDebugStr,
- kODCommandDBSOMTrace,
- kODCommandDBBreakOnThrow,
- kODCommandDBEatMemory,
- kODCommandDBPurge
- };
-
- const short kODHeapInfoAlert = 980;
- #endif
-
- const StringPtr kODEmptyPString = "\p";
-
- //==============================================================================
- // Local Macros
- //==============================================================================
-
- #if ODDebug
- #define SHLDebugStr(x) DebugStr(x)
- #else
- #define SHLDebugStr(x)
- #endif
-
- #define BITTEST( codes, thisCode ) \
- (((codes) & (thisCode)) != 0L)
-
- //#define SHLHeapDebug
- //#define SHLTestSessionOverhead
- //#define SHLTestErrorDialogUsage
-
- //==============================================================================
- // Static variables
- //==============================================================================
-
- #if ODDebug
- static ODBoolean gMemValidation = kODFalse;
- static ODBoolean gHeapChecking = kODFalse;
- static ODBoolean gLeakChecking = kODFalse;
- static ODBoolean gDumpBlocksOnClose = kODFalse;
- static ODBoolean gTrackStackCrawls = kODFalse;
- #endif
-
- #ifndef __MWERKS__
- QDGlobals qd;
- #endif
- // Need to declare 'qd' ourselves because even though 'qd' is already
- // in Startup.c in the Metrowerks libraries, it is NOT necessarily in the
- // libraries for other compilers, e.g the compilers for CFM68K. -TÇ
-
- //==============================================================================
- // Local Classes
- //==============================================================================
-
- struct ErrRecord
- {
- ODError lowErr, highErr;
- ODULong index;
- };
-
- typedef ErrRecord* ErrRecordPointer;
- typedef ErrRecordPointer* ErrRecordHandle;
-
- //==============================================================================
- // Function Prototype
- //==============================================================================
-
- void CreateTempName(short seed, Str255 name, ODBoolean isFile);
- // $opt: CreateTempName is duplicated in ODPrcs.cpp
-
- void GetTempFolder(ODSShort* VRef,ODSLong* DirID);
- void CreateNewFile(PlatformFile* newFile, ODBoolean forceNewName); // newFile is in/out
-
- pascal void DrawSmallIcon(DialogPtr theDialog, short theItem);
- pascal short SaveCopyDlgHook(short item, DialogPtr theDialog, void *yourDataPtr);
-
- #if ODDebug
- static ODBoolean isHeapKeyDown();
-
- static ODBoolean isFilterKeyDown();
-
- static void HeapInfo();
-
- #endif
-
- ODStatic void FindShellPlugInsFolder(short *vol, long *dir );
- ODStatic void FindStationeryFolder(short *vol, long *dir );
-
- ODStatic void CreateNewUntitledFile(PlatformFile* newFile,
- char* fileNameSeed = kODNULL);
- // Note: fileNameSeed is ignored if newFile->IsStationery()
-
- static ODIText* CreateDefaultIText(StringPtr text);
- static OSErr SendFinderODOCEvent( const FSSpec *fileToOpen );
- ODStatic OSErr GetCfrgInfo( ODFileSpec* fileSpec, long* offset, long* length );
- ODStatic void CopyResources(PlatformFile* srcFile, PlatformFile* dstFile);
-
-
- extern ODBoolean gODBentoFatalErrorHasOccurred; // SessHdr.cpp
- extern ODBoolean gODDelayBentoFatalError; // SessHdr.cpp
- extern ODBoolean gODSuppressBentoFatalError; // SessHdr.cpp
- extern void ODBentoFatalError(ODBoolean allowSuppress); // SessHdr.cpp
-
- #if ODDebug
- static void DumpHeapObjects( ODBoolean objectsOnly );
- #endif
-
- void FinderNotRunning();
-
- //==============================================================================
- // ShellMain Function
- //==============================================================================
-
- #pragma lib_export on // only ShellMain needs to be exported
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- int ShellMain()
- {
- MaxApplZone();
- MoreMasters();
- MoreMasters();
- MoreMasters();
- MoreMasters(); // $Opt: May need more of these. Poke about at runtime to see.
-
- InitGraf(&qd.thePort);
-
- InitFonts();
- FlushEvents(everyEvent, 0);
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(kODNULL);
- WatchCursor();
-
- // Intialize Metrowerks profiler if this is a profiling build:
- #ifdef __MWERKS__
- #if __option(profile)
- ProfilerInit(collectDetailed,bestTimeBase,3000,100);
- ProfilerSetStatus(false);
- #endif
- #endif
-
- /* Note below that we continue even if the Edition Manager or TSM are not around.
- There is no express reason that either one of these need to be around for OpenDoc
- in general to function. Lack of Edition Manager just means you can't do linking.
- */
-
- if (InitEditionPack() != noErr)
- SHLDebugStr("\pInitEditionPack failed");
-
- long gestaltResponse;
- ODBoolean hasTSM = (Gestalt(gestaltTSMgrVersion, &gestaltResponse) == noErr) &&
- (gestaltResponse >= 1);
- if (hasTSM)
- {
- if (InitTSMAwareApplication() == noErr)
- {
- const TSMDocumentID kAnyDoc = kODNULL;
-
- if (UseInputWindow(kAnyDoc, kODTrue) != noErr)
- SHLDebugStr("\pUseInputWindow failed.");
- }
- else
- {
- SHLDebugStr("\pInitTSMAwareApplication failed.");
- }
- }
- else
- {
- SHLDebugStr("\pTSM unavailable.");
- }
-
- TRY
- ODInitExceptions(); // Sets up SOMError and SOMPrintf
-
- // CHECK FOR RUNNING UNDER MacOS8
- {
- CUsingLibraryResources r;
-
- if (RunningUnderMacOS8())
- return 1;
- }
-
- #if ODDebug
- MMBeginMemValidation();
- gMemValidation = kODTrue;
- #endif
-
- #if VALIDATE_EVERYTHING
- // MMBeginMemValidation(); Should be taken care of by above.
- MMBeginHeapChecking( );
- #endif
-
- if (IsOptionKeyDown())
- SHLDebugStr("\pAbout to create and enter the Shell. You may proceed.");
-
- #if ODDebug
- if (isHeapKeyDown())
- {
- SHLDebugStr("\pAbout to track heap block stack crawls. Type g to proceed.");
- gDumpBlocksOnClose = kODTrue;
- gTrackStackCrawls = kODTrue;
- }
- #endif
-
- RealShell* le = new RealShell;
- le->go();
- delete le;
-
- #if VALIDATE_EVERYTHING
- MMEndHeapChecking( );
- MMEndMemValidation();
- #endif
-
- if (hasTSM)
- CloseTSMAwareApplication();
- CATCH_ALL
- /* Not much we can do here folks.
- Either ODInitExceptions failed, or creating a RealShell object failed.
- If the latter, then we don't have enough memory to put up a dialog.
- If the former, then something is really wrong the runtime.
- */
- SHLDebugStr("\pException reached ShellMain. Possibly ODInitExceptions failed");
- ENDTRY
-
- return 0;
- }
-
- #ifdef __cplusplus
- }
- #endif
-
- #pragma lib_export off
-
- //==============================================================================
- // Static Functions
- //==============================================================================
-
- #if ODDebug
- static ODBoolean isHeapKeyDown() // use 'h' to mean "heap"
- {
- const ODUShort heapKey = 4; // the 'h' key
- return IsThisKeyDown(heapKey);
- }
- static ODBoolean isFilterKeyDown() // use 'f' to mean "filter"
- {
- const ODUShort filterKey = 3; // the 'f' key
- return IsThisKeyDown(filterKey);
- }
- #endif
-
- #if ODDebug
-
- static void
- ParamTextHeapInfo( )
- {
- const char *name;
- size_t allocated, free,blocks,objects,contig;
-
- MMGetHeapInfo(kDefaultHeapID,
- &name, &allocated, &free, &blocks, &objects);
- char nameStr[256], infoStr[256], appInfoStr[256];
- strcpy((char*)nameStr, name);
- sprintf(infoStr,"%lu\r%lu (%.1f%%)\r%lu (%lu objs)",
- allocated, free,
- 100.0*free/(float)(allocated+free),
- blocks,objects);
-
- MMSystemFreeSpace(kMMAppMemory, &free,&contig);
- allocated = (ApplicationZone()->bkLim-(Ptr)&ApplicationZone()->heapData) - free;
- sprintf(appInfoStr,"%lu\r%lu (%.1f%%)\r%lu",
- allocated, free,
- 100.0*free/(float)(allocated+free),
- contig);
-
- ParamText(CToPascalString(nameStr),CToPascalString(infoStr),
- "\pMacOS Application Heap",CToPascalString(appInfoStr));
- }
-
- static void HeapInfo()
- {
- ParamTextHeapInfo();
- ODSLong savedRefNum;
- BeginUsingLibraryResources(savedRefNum);
- NoteAlert(kODHeapInfoAlert, NULL);
- EndUsingLibraryResources(savedRefNum);
- }
-
- #endif
-
-
- //==============================================================================
- // RealShell
- //==============================================================================
-
-
- //-------------------------------------------------------------------------------------
- // Initialization
- //-------------------------------------------------------------------------------------
-
- RealShell::RealShell()
- {
- fEV = kODNULL;
- fSession = kODNULL;
- fDispatcher = kODNULL;
- fWindowState = kODNULL;
- fArbitrator = kODNULL;
- fSIHelper = kODNULL;
-
- fModalFocusToken = kODNullTypeToken;
- fAlreadyInCoercion = kODFalse;
- fErrorFromOpenEvents = noErr;
- fUniqueNameSeed = 1;
- fShellHasMenuFocus = kODFalse;
- fLastNewDocPSN.lowLongOfPSN = kNoProcess;
-
- fSaveCopyData = kODNULL;
- fSaveDiffVolDialog = kODNULL;
-
- fLowMemNotified = kODFalse;
-
- fFailedPlugInName[0] = 0;
- }
-
-
- RealShell::~RealShell()
- {
-
- ODDeleteObject(fSIHelper);
-
- this->ExportClipboard(kODFalse);
- #ifdef SHLHeapDebug
- SHLDebugStr("\pPostCloseDoc/PreSessionDelete HeapInfo…");
- HeapInfo();
- #endif
- delete fSession;
- #ifdef SHLHeapDebug
- SHLDebugStr("\pPostSessionDelete HeapInfo…");
- HeapInfo();
- #endif
-
- #if ODDebug
- if( gDumpBlocksOnClose ) {
- somPrintf("SOM objects and tracked blocks in heap contents after closing the session:\n");
- DumpHeapObjects(/*objectsOnly*/ kODFalse);
- }
- #endif
- WASSERT(fSaveDiffVolDialog==kODNULL);
- }
-
-
-
- void RealShell::Initialize()
- {
- // Force NewPtr to allocate in our heap in temp mem. This fixes the problem
- // of CFM global data choking the app heap!
- MMOverridePlatform(kODTrue,kODFalse);
-
- fEV = somGetGlobalEnvironment();
-
- fSession = new ODSession;
- THROW_IF_NULL(fSession); // som objects don't autothrow if unable to allocate.
- fSession->InitSession(fEV);
- // Note: we need fDispatcher & fWindowState BEFORE ShellPlugIns are installed.
- fDispatcher = fSession->GetDispatcher(fEV);
- fWindowState = fSession->GetWindowState(fEV);
- fArbitrator = fSession->GetArbitrator( fEV );
-
- fModalFocusToken = fSession->Tokenize( fEV, kODModalFocus );
-
- // Is the app curently the active process?
- ProcessSerialNumber me = {0,kCurrentProcess};
- ProcessSerialNumber cur;
- GetFrontProcess(&cur);
- SameProcess(&me,&cur,&fProcessIsActive);
-
- // Is this an APPL process or a normal OD doc process?
- ProcessInfoRec info;
- this->GetCurrentProcessInfo(&info);
- fAPPLProcess = (info.processType=='APPL');
-
- this->InstallMenuBar();
- this->InitAE();
- this->InitMemory();
- }
-
- void RealShell::InstallMenuBar()
- {
- ODSLong savedRefNum;
- BeginUsingLibraryResources(savedRefNum);
-
- ODPlatformMenuBar menuBar;
- menuBar = GetNewMBar(kODAppleMenuID);
-
- if( !menuBar ) THROW(resNotFound);
- SetMenuBar(menuBar);
-
- MenuHandle appleMenu = GetMenuHandle(kODAppleMenuID);
- DetachResource((Handle)appleMenu);
-
- #if ODDebugMenu
- // Add "ODDebug" menu item, with submenu, below "About..." command:
- InsertMenuItem(appleMenu,"\pODDebug",1);
- SetItemCmd(appleMenu,2,0x1B);
- SetItemMark(appleMenu,2, kDebugMenuID);
-
- MenuHandle dbMenu = NewMenu(kDebugMenuID,"\pODDebug");
- THROW_IF_NULL(dbMenu);
- AppendMenu(dbMenu, "\pHeap Info;"
- "Memory Validation;"
- "Heap Checking;"
- "Leak Checking;"
- "Dump Blocks On Close;"
- "Track Block Stack Crawls;"
- "Eat Memory;"
- "Purge;"
- "(-;"
- "Log To stdout File;"
- "Log To DebugWindow;"
- "Generate DebugStrs;"
- "Dump ODObjects;"
- "Dump Tracked Blocks;"
- "(-;"
- "Break On THROW;"
- "SOM Trace" );
- InsertMenu(dbMenu,hierMenu);
-
- const int kNumDebugMenuItems = 17;
-
- static const ODCommandID kDBCommands[kNumDebugMenuItems] = {kODCommandDBHeapInfo,
- kODCommandDBMemValidation,
- kODCommandDBHeapChecking,
- kODCommandDBLeakChecking,
- kODCommandDBDumpBlocksOnClose,
- kODCommandDBTrackStackCrawls,
- kODCommandDBEatMemory,
- kODCommandDBPurge,
- /* Used below... */ 0,
- kODCommandDBLogStdout,
- kODCommandDBLogDebugWindow,
- kODCommandDBLogDebugStr,
- kODCommandDBDumpObjects,
- kODCommandDBDumpBlocks,
- 0,
- kODCommandDBBreakOnThrow,
- kODCommandDBSOMTrace};
-
- DisposeHandle((Handle)menuBar); // Update menuBar variable with new menu
- menuBar = GetMenuBar();
- #endif
-
- // create a new ODMenuBar object
- TempODMenuBar baseMenuBar = fWindowState->CreateMenuBar(fEV, menuBar);
-
- // add DA names to Apple menu
- AppendResMenu(appleMenu, kODDASMenuRsrc);
-
- #ifdef SUPPORT_QUIT
- // Load Document menu, or File menu if running in an 'APPL' process: [MenuIDs are identical!]
- MenuHandle documentMenu = GetMenu( fAPPLProcess ?kODFileMenuID :kODDocumentMenuID);
- #else
- MenuHandle documentMenu = GetMenu(kODDocumentMenuID);
- #endif
-
- DetachResource((Handle)documentMenu);
-
- baseMenuBar->AddMenuLast(fEV, kODDocumentMenuID, documentMenu, kODNULL);
-
- MenuHandle editMenu = GetMenu(kODEditMenuID);
- DetachResource((Handle)editMenu);
- baseMenuBar->AddMenuLast(fEV, kODEditMenuID, editMenu, kODNULL);
-
- // Save off the default undo and redo menu items so that we can use them when
- // there's nothing on the undo or redo stack.
-
- this->SaveMenuItem(appleMenu, kSHLMenuAbout, &fDefaultAboutMenuItem);
- this->SaveMenuItem(editMenu, kSHLMenuUndo, &fDefaultUndoMenuItem);
- this->SaveMenuItem(editMenu, kSHLMenuRedo, &fDefaultRedoMenuItem);
- this->SaveMenuItem(editMenu, kSHLMenuPreferences, &fDefaultPrefsMenuItem);
-
- EndUsingLibraryResources(savedRefNum);
-
- baseMenuBar->RegisterCommand(fEV, kODCommandAppleMenu, kODAppleMenuID, 0);
- baseMenuBar->RegisterCommand(fEV, kODCommandAbout, kODAppleMenuID, kSHLMenuAbout);
-
- baseMenuBar->RegisterCommand(fEV, kODCommandDocumentMenu, kODDocumentMenuID, 0);
- baseMenuBar->RegisterCommand(fEV, kODCommandNew, kODDocumentMenuID, kSHLMenuNew);
- baseMenuBar->RegisterCommand(fEV, kODCommandOpen, kODDocumentMenuID, kSHLMenuOpen);
- baseMenuBar->RegisterCommand(fEV, kODCommandOpenDocument, kODDocumentMenuID, kSHLMenuOpenDocument);
- baseMenuBar->RegisterCommand(fEV, kODCommandInsert, kODDocumentMenuID, kSHLMenuInsert);
- baseMenuBar->RegisterCommand(fEV, kODCommandClose, kODDocumentMenuID, kSHLMenuClose);
- baseMenuBar->RegisterCommand(fEV, kODCommandDeleteDocument, kODDocumentMenuID, kSHLMenuDeleteDocument);
-
- baseMenuBar->RegisterCommand(fEV, kODCommandSave, kODDocumentMenuID, kSHLMenuSave);
- baseMenuBar->RegisterCommand(fEV, kODCommandSaveACopy, kODDocumentMenuID, kSHLMenuSaveACopy);
- baseMenuBar->RegisterCommand(fEV, kODCommandRevert, kODDocumentMenuID, kSHLMenuRevert);
- baseMenuBar->RegisterCommand(fEV, kODCommandDraft, kODDocumentMenuID, kSHLMenuDraft);
- baseMenuBar->RegisterCommand(fEV, kODCommandDocumentInfo, kODDocumentMenuID, kSHLMenuDocumentInfo);
-
- baseMenuBar->RegisterCommand(fEV, kODCommandPageSetup, kODDocumentMenuID,
- kSHLMenuPageSetup );
- baseMenuBar->RegisterCommand(fEV, kODCommandPrint, kODDocumentMenuID,
- kSHLMenuPrint );
-
- #ifdef SUPPORT_QUIT
- // If this is an APPL process like CyberDog, register "Quit" cmd
- if( fAPPLProcess )
- baseMenuBar->RegisterCommand(fEV, kODCommandQuit, kODDocumentMenuID, kSHLMenuQuit);
- #endif
-
- baseMenuBar->RegisterCommand(fEV, kODCommandEditMenu, kODEditMenuID, 0);
- baseMenuBar->RegisterCommand(fEV, kODCommandUndo, kODEditMenuID, kSHLMenuUndo);
- baseMenuBar->RegisterCommand(fEV, kODCommandRedo, kODEditMenuID, kSHLMenuRedo);
- baseMenuBar->RegisterCommand(fEV, kODCommandCut, kODEditMenuID, kSHLMenuCut);
- baseMenuBar->RegisterCommand(fEV, kODCommandCopy, kODEditMenuID, kSHLMenuCopy);
- baseMenuBar->RegisterCommand(fEV, kODCommandPaste, kODEditMenuID, kSHLMenuPaste);
- baseMenuBar->RegisterCommand(fEV, kODCommandPasteAs, kODEditMenuID, kSHLMenuPasteAs);
- baseMenuBar->RegisterCommand(fEV, kODCommandClear, kODEditMenuID, kSHLMenuClear);
- baseMenuBar->RegisterCommand(fEV, kODCommandSelectAll, kODEditMenuID, kSHLMenuSelectAll);
- baseMenuBar->RegisterCommand(fEV, kODCommandGetPartInfo, kODEditMenuID, kSHLMenuGetPartInfo);
- baseMenuBar->RegisterCommand(fEV, kODCommandPreferences, kODEditMenuID, kSHLMenuPreferences);
- baseMenuBar->RegisterCommand(fEV, kODCommandViewAsWin, kODEditMenuID, kSHLMenuViewAsWin);
-
- #if ODDebugMenu
- for( short i=0; i<kNumDebugMenuItems; i++ )
- if( kDBCommands[i] )
- baseMenuBar->RegisterCommand(fEV, kDBCommands[i], kDebugMenuID, i+1);
- #endif
-
- fWindowState->SetBaseMenuBar(fEV,baseMenuBar);
- baseMenuBar->Display(fEV);
- }
-
- //------------------------------------------------------------------------------
- // RealShell::SaveMenuItem
- //------------------------------------------------------------------------------
-
- void
- RealShell::GetCurrentProcessInfo( ProcessInfoRec *info, StringPtr name, FSSpec *appLoc )
- {
- ProcessSerialNumber psn = {0,kCurrentProcess};
- info->processInfoLength = sizeof(ProcessInfoRec);
- info->processName = name;
- info->processAppSpec = appLoc;
- THROW_IF_ERROR( GetProcessInformation(&psn,info) );
- }
-
-
- //------------------------------------------------------------------------------
- // RealShell::SaveMenuItem
- //------------------------------------------------------------------------------
-
- void RealShell::SaveMenuItem(MenuHandle menu, short itemNum, MenuItemInfo* info)
- {
- GetMenuItemText(menu, itemNum, (*info).text);
- GetItemCmd(menu, itemNum, &(*info).cmdChar);
- GetItemIcon(menu, itemNum, &(*info).iconID);
- GetItemMark(menu, itemNum, &(*info).markChar);
- GetItemStyle(menu, itemNum, &(*info).textStyle);
- }
-
- //------------------------------------------------------------------------------
- // RealShell::RestoreMenuItem
- //------------------------------------------------------------------------------
-
- void RealShell::RestoreMenuItem(MenuHandle menu, short itemNum, MenuItemInfo* info)
- {
- SetMenuItemText(menu, itemNum, (*info).text);
- SetItemCmd(menu, itemNum, (*info).cmdChar);
- SetItemIcon(menu, itemNum, (*info).iconID);
- SetItemMark(menu, itemNum, (*info).markChar);
- SetItemStyle(menu, itemNum, (*info).textStyle);
- }
-
- //------------------------------------------------------------------------------
- // RealShell::InstallShellPlugIns
- //------------------------------------------------------------------------------
-
- void RealShell::InstallShellPlugIns(ODDraft* draft)
- {
- // get reference to OpenDoc Shell PlugIns directory
- ODSShort fldrVRefNum=0;
- ODSLong fldrDirID=0;
-
- TRY{
- FindShellPlugInsFolder(&fldrVRefNum, &fldrDirID);
- this->ScanShellPlugInsFldr(fldrVRefNum, fldrDirID, draft);
- }CATCH_ALL{
- if ( fFailedPlugInName[0] )
- RERAISE;
- }ENDTRY
-
- }
-
- //------------------------------------------------------------------------------
- // GetInstallEntryPt
- // Given a file spec, find the record within the 'cfrg' resource in that
- // file that corresponds to the platform we're on and the symbol we're
- // looking for. Loop through all entries until finding one that has
- // the entry point we're looking for.
- //------------------------------------------------------------------------------
- ODStatic OSErr GetInstallEntryPt( ODFileSpec* fileSpec, ODShellPlugInInstallProc* entryPt,
- CFragConnectionID* connIDPtr )
- {
- #if PRAGMA_ALIGN_SUPPORTED
- #pragma options align=mac68k
- #endif
-
- struct FragDesc {
- ResType codeType;
- long ignore[5];
- long offsetToFrag;
- long lengthOfFrag;
- long moreIgnore[2];
- short recordLength;
- Str63 name;
- };
-
- struct CFRGResource {
- long ignore[7];
- long numFrags;
- struct FragDesc firstDesc;
- };
-
- #if PRAGMA_ALIGN_SUPPORTED
- #pragma options align=reset
- #endif
-
- OSErr err = resNotFound;
-
- short refNum = HOpenResFile( fileSpec->vRefNum, fileSpec->parID,
- fileSpec->name, fsRdPerm );
- short saveRefNum = CurResFile();
- UseResFile( refNum );
-
- struct CFRGResource** cfrgHandle =
- (struct CFRGResource**)Get1Resource( 'cfrg', 0 );
- if ( cfrgHandle )
- {
- long entryCount = (*cfrgHandle)->numFrags;
- struct FragDesc* oneEntryPtr = &(*cfrgHandle)->firstDesc;
- while ( entryCount-- )
- {
- // for each fragment, if it's the right architecture
- // see if it has an entrypoint of the right name.
- // Keep going until found or all exhausted (bug 1322456)
- if ( oneEntryPtr->codeType == kCurrentCFragArch )
- {
- CFragConnectionID connID;
- Ptr ignoreMainAddr;
- Str255 errName;
- err = GetDiskFragment( fileSpec,
- oneEntryPtr->offsetToFrag,
- oneEntryPtr->lengthOfFrag,
- NULL, kNewCFragCopy, &connID, &ignoreMainAddr,
- errName );
- if ( err == noErr )
- {
- ODShellPlugInInstallProc installMethod;
- CFragSymbolClass symClass;
- err = FindSymbol( connID, "\pODShellPlugInInstall",
- (Ptr*)&installMethod, &symClass );
- if ( err == noErr ) // we're done
- {
- WASSERT( symClass == kTVectorCFragSymbol );
- *entryPt = installMethod;
- *connIDPtr = connID;
- break;
- }
- else // we opened it but don't want it; free the memory
- CloseConnection( &connID );
- }
- }
- // else
- oneEntryPtr = (FragDesc*)(oneEntryPtr->recordLength
- + (char*)oneEntryPtr);
- }
- }
- else
- err = ResError();
-
- CloseResFile( refNum );
- UseResFile( saveRefNum );
- return err;
- } // GetInstallEntryPt()
-
- //------------------------------------------------------------------------------
- // RealShell::ScanShellPlugInsFldr
- //------------------------------------------------------------------------------
-
- void RealShell::ScanShellPlugInsFldr(ODSShort fldrVRefNum, ODSLong fldrDirID,
- ODDraft* draft)
- {
- // iterate through files in that directory (code copied from Prefs.cpp:LoadNameSpaceTable)
- ODFileSpec theFileSpec;
- CInfoPBRec CinfoPB;
- Str255 fileName;
-
- memset (&CinfoPB,0,sizeof(CinfoPB));
- CinfoPB.hFileInfo.ioNamePtr = (StringPtr)fileName;
- CinfoPB.hFileInfo.ioFDirIndex = 1;
- CinfoPB.hFileInfo.ioVRefNum = fldrVRefNum;
- CinfoPB.hFileInfo.ioDirID = fldrDirID;
-
- TempPlatformFile file(new PlatformFile);
-
- for( ODSShort i = PBGetCatInfoSync( &CinfoPB );
- i == noErr;
- i = PBGetCatInfoSync( &CinfoPB ) )
- {
- // if this is not a folder and we successfully create an FSSpec
- if (( ! (CinfoPB.hFileInfo.ioFlAttrib & (1<<4)) )
- && ( noErr == (FSMakeFSSpec( CinfoPB.hFileInfo.ioVRefNum,
- CinfoPB.hFileInfo.ioFlParID, //ioDirID,
- fileName,
- &theFileSpec ) ) ))
- {
- file->Specify(&theFileSpec);
- if ( file->GetPlatformType() == kCFragLibraryFileType)
- {
- CFragConnectionID connID;
- ODShellPlugInInstallProc installMethod;
- OSErr err = GetInstallEntryPt( &theFileSpec,
- &installMethod, &connID );
-
- ODShellPlugInActionCodes action
- = kODShellPlugInNoAction;
- if ( !err )
- {
- TRY
- err = (*installMethod)( fEV, draft, &action );
- CATCH_ALL
- SetErrorCode(kODNoError);
- ENDTRY
- }
- // else is not a shell plugin; continue with next file
-
- // test again; if the FindSymbol call failed we
- // still want to close the connection
- if ( (err != noErr) ||
- BITTEST(action, kODShellPlugInCloseConnection) )
- err = CloseConnection( &connID );
-
- if ( err )
- {
- ODBlockMove( theFileSpec.name, fFailedPlugInName,
- theFileSpec.name[0]+1 );
- THROW( err );
- }
- }
- }
- CinfoPB.hFileInfo.ioFDirIndex++;
-
- //need to do this each time since PBGetCatInfo call returns val here
- CinfoPB.hFileInfo.ioNamePtr = (StringPtr)fileName;
- CinfoPB.hFileInfo.ioVRefNum = fldrVRefNum;
- CinfoPB.hFileInfo.ioDirID = fldrDirID;
- }
- }
-
- //------------------------------------------------------------------------------
- // FindShellPlugInsFolder //ccg
- //------------------------------------------------------------------------------
-
- static void FindShellPlugInsFolder(short *vol, long *dir )
- {
- Str255 folderName;
-
- CInfoPBRec pb;
- memset (&pb,0,sizeof(pb));
-
- //First find System Folder
- THROW_IF_ERROR( FindFolder(kOnSystemDisk, kSystemFolderType, kDontCreateFolder,
- &pb.dirInfo.ioVRefNum, &pb.dirInfo.ioDrDirID) );
-
- // find Shell Plug Ins Folder path name
- ODGetString(folderName, kODEditorsFldrStrID);
- pb.dirInfo.ioNamePtr = (StringPtr)&folderName;
- pb.dirInfo.ioFDirIndex = 0;
- THROW_IF_ERROR( PBGetCatInfoSync( &pb ) );
-
- ODGetString(folderName, kODOpenDocPartsFolderStrID);
- pb.dirInfo.ioNamePtr = (StringPtr)&folderName;
- pb.dirInfo.ioFDirIndex = 0;
- THROW_IF_ERROR( PBGetCatInfoSync( &pb ) );
-
- ODGetString(folderName, kODShellPlugInFolderStrID);
- pb.dirInfo.ioNamePtr = (StringPtr)&folderName;
- pb.dirInfo.ioFDirIndex = 0;
- THROW_IF_ERROR( PBGetCatInfoSync( &pb ) );
-
- *vol = pb.dirInfo.ioVRefNum;
- *dir = pb.dirInfo.ioDrDirID;
- }
- //------------------------------------------------------------------------------
- // FindStationeryFolder
- //------------------------------------------------------------------------------
- static void FindStationeryFolder(short *vol, long *dir )
- {
- Str255 folderName;
- ODSLong unused;
-
- CInfoPBRec pb;
- memset (&pb,0,sizeof(pb));
-
- //First find Desktop Folder
- THROW_IF_ERROR( FindFolder(kOnSystemDisk, kDesktopFolderType, kCreateFolder,
- vol, &unused ));
-
- // find Stationery Folder path name
- ODGetString(folderName, kODStationeryFldrStrID);
- pb.dirInfo.ioNamePtr = (StringPtr)&folderName;
- pb.dirInfo.ioDrDirID = fsRtDirID; //2;
- pb.dirInfo.ioVRefNum = *vol;
- pb.dirInfo.ioFDirIndex = 0;
- if ( PBGetCatInfoSync( &pb ) )
- {
- THROW_IF_ERROR(
- DirCreate(*vol, fsRtDirID, folderName, dir));
- } else {
- *dir = pb.dirInfo.ioDrDirID;
- }
- }
-
- //-------------------------------------------------------------------------------------
- // RealShell::go
- //-------------------------------------------------------------------------------------
-
- void RealShell::go()
- {
- ODBoolean initialized;
- ODVolatile(initialized);
- ODULong errorLoops = 0; // Counts the number of times in a row we caught
- // an out-of-memory error in the event loop.
- ODVolatile(errorLoops);
-
- #if ODDebug
- if ( gDumpBlocksOnClose )
- {
- SetOutputMode(kWriteToFile);
- // MMBeginLeakChecking();
- // gLeakChecking = kODTrue;
- MMTrackStackCrawls( kODTrue );
- }
- #endif
-
- {
- TRY
- this->Initialize();
- initialized = kODTrue;
- CATCH_ALL
- initialized = kODFalse;
- ODShellLowMemoryGoodbye();
- // THIS CALL USES OD SERVICES THAT MAY NOT BE THERE!
- // this->ExceptionAlert(ErrorCode(),ErrorMessage());
- ENDTRY
- }
-
- #ifdef SHLTestErrorDialogUsage
- SHLDebugStr("\pPreErrorDialog HeapInfo…");
- HeapInfo();
- this->ExceptionAlert(1,kODNULL);
- #endif
-
- #ifdef SHLTestSessionOverhead
- SHLDebugStr("\pPreExtraSession HeapInfo…");
- HeapInfo();
-
- TRY
- TempODSession aSession = new ODSession;
- THROW_IF_NULL(aSession); // som objects don't autothrow if unable to allocate.
- aSession->InitSession(fEV);
- CATCH_ALL
- ENDTRY
-
- SHLDebugStr("\pPostExtraSession HeapInfo…");
- HeapInfo();
- #endif
-
- EventRecord eventRec;
- if (initialized)
- while (!fDispatcher->ShouldExit(fEV))
- {
- TRY
- gODDelayBentoFatalError = gODSuppressBentoFatalError = kODFalse;
- if ( gODBentoFatalErrorHasOccurred )
- ODBentoFatalError(/*allowSuppress*/ kODFalse);
-
- if( this->CheckFileLocation() ) // Update if document renamed/moved
- break; // we may need to quit if trashed
-
- ODSLong sleep = fDispatcher->GetSleepTime(fEV);
- if( sleep > kMaxTimeBetweenLocationChecks )
- sleep = kMaxTimeBetweenLocationChecks;
-
- WaitNextEvent (everyEvent, &eventRec, sleep, fDispatcher->GetMouseRegion(fEV));
- if( eventRec.what == osEvt && (( eventRec.message >> 24 ) & 0x00FF)==0x01 )
- fProcessIsActive= (eventRec.message & 0x01)!=0;
-
- this->DispatchEvent((ODEventData*)&eventRec);
-
- this->CheckMenuBar();
-
- if( fProcessIsActive )
- this->CheckFreeMemory(); // Display low-mem alert
-
- errorLoops = 0; // Reset this. We got through the loop OK.
-
- CATCH_ALL
-
- // IF WE CATCH A LOW-MEMORY ERROR HERE MORE THAN 2 TIMES IN A ROW,
- // WE OUTTIE.
- ODError thisError = ErrorCode();
- if (thisError == kODErrOutOfMemory || thisError == memFullErr)
- {
- ++errorLoops;
- if (errorLoops > 2)
- ODShellLowMemoryGoodbye();
- }
-
- this->ExceptionAlert(ErrorCode(),ErrorMessage());
-
- ENDTRY
-
- }
-
- // Check to see if we failed in the odoc or oapp appleevent handlers.
- ODError err = this->GetAEError();
- if (err)
- {
- this->ExceptionAlert(err,kODNULL);
- }
- }
-
-
- //-------------------------------------------------------------------------------------
- // Notification Stuff
- //-------------------------------------------------------------------------------------
-
- struct NotEntry :public Link {
- RealShell::Notifier n;
- ODULong refCon;
- NMRec nm;
-
- virtual ~NotEntry( );
- };
-
- NotEntry::~NotEntry( )
- {
- if( nm.nmIcon ) DisposeIconSuite(nm.nmIcon,kODTrue);
- }
-
- static ODIconFamily
- GetRootPartIconFamily( Environment* ev, ODSession* session )
- {
- static ODIconFamily sIcon = kODNULL;
- if( !sIcon ) {
- TempODWindow odWindow = session->GetWindowState(ev)->AcquireFrontRootWindow(ev);
- ODFrame* rootFrame = odWindow ? odWindow->GetRootFrame(ev) : kODNULL;
- sIcon = ODGetIconFamily(ev, rootFrame);
- }
- return sIcon;
- }
-
-
- //-------------------------------------------------------------------------------------
- // RealShell::Notify
- //-------------------------------------------------------------------------------------
-
- void
- RealShell::Notify( RealShell::Notifier n, ODULong refCon )
- {
- if( fProcessIsActive )
- (this->*n)( refCon ); // We're active, so call notifier right now.
-
- else {
- NotEntry *e = new NotEntry;
- e->n = n;
- e->refCon = refCon;
- fNotifiers.AddLast(e);
-
- e->nm.qType = nmType;
- e->nm.nmMark = 1; // Mark process menu
- e->nm.nmIcon = GetRootPartIconFamily(fEV, fSession); // Show root part's icon
- e->nm.nmSound = (Handle)-1L; // Play system beep
- e->nm.nmStr = kODNULL;
- e->nm.nmResp = kODNULL;
- OSErr err= NMInstall(&e->nm);
- WASSERT(err==noErr);
- }
- }
-
-
- //-------------------------------------------------------------------------------------
- // RealShell::CancelNotification
- //-------------------------------------------------------------------------------------
-
- void
- RealShell::CancelNotification( RealShell::Notifier n )
- {
- // Removes all notifications pointing to this notifier proc.
- NotEntry *next;
- for( NotEntry *e = (NotEntry*)fNotifiers.First(); e; e=next ) {
- next = (NotEntry*)fNotifiers.After(*e);
- if( e->n == n ) {
- NMRemove(&e->nm);
- fNotifiers.Remove(*e);
- delete e;
- }
- }
- }
-
-
- //-------------------------------------------------------------------------------------
- // RealShell::ShowPendingNotification
- //-------------------------------------------------------------------------------------
-
- void
- RealShell::ShowPendingNotifications( )
- {
- if( fProcessIsActive ) {
- NotEntry *e;
- while( !fNotifiers.IsEmpty() ) {
- e = (NotEntry*) fNotifiers.RemoveFirst();
- NMRemove(&e->nm);
- (this->*(e->n))( e->refCon ); // Call notifier method
- delete e;
- }
- }
- }
-
-
- //-------------------------------------------------------------------------------------
- // RealShell::DispatchEvent
- //-------------------------------------------------------------------------------------
-
- void RealShell::DispatchEvent(ODEventData* event)
- {
- switch (event->what)
- {
- case kODEvtMouseDown:
- this->DispatchMouseDownEvent(event);
- break;
-
- case kODEvtKeyDown:
- this->DispatchKeyDownEvent(event);
- break;
-
- case kODEvtOS:
- // FOR NOW, EAT ALL ERRORS OCCURING DURING A SUSPEND.
- // SEE WHAT TYPE OF OS EVENT IT IS
- ODUByte typeOSEvent = (ODUByte) (event->message >> 24) & 0x00FF;
- ODBoolean isSuspendEvent;
-
- // IF IT'S A SUSPEND MESSAGE
- isSuspendEvent = ((typeOSEvent & suspendResumeMessage)
- && (!(event->message & resumeFlag)));
- TRY
- fDispatcher->Dispatch(fEV,event);
- this->HandleOSEvent(event);
- CATCH_ALL
- if (isSuspendEvent)
- WARN("Eating an error that occurred during suspend time.");
- else
- RERAISE;
- ENDTRY
- break;
-
- case kHighLevelEvent:
- if (!fDispatcher->Dispatch(fEV,event))
- this->HandleHighLevelEvent(event);
- break;
-
- default:
- fDispatcher->Dispatch(fEV,event);
- break;
- }
- }
-
- //-------------------------------------------------------------------------------------
- // RealShell::DispatchMouseDownEvent
- //-------------------------------------------------------------------------------------
-
- void RealShell::DispatchMouseDownEvent(ODEventData* event)
- {
- WindowPtr theWindow = kODNULL;
- ODSShort partCode = FindWindow(event->where, &theWindow);
- if (partCode == kODMDInMenuBar)
- this->DispatchMenuEvent(event);
- else if (!(fDispatcher->Dispatch(fEV,event)) && theWindow)
- this->HandleMouseDownInWindow(theWindow, partCode, event);
- }
-
- //-------------------------------------------------------------------------------------
- // RealShell::DispatchMenuEvent
- //-------------------------------------------------------------------------------------
-
- void RealShell::DispatchMenuEvent(ODEventData* event)
- {
- this->UpdateMenus();
- if (!(fDispatcher->Dispatch(fEV,event)))
- this->HandleMenuCommand(event->message, event);
- }
-
- //-------------------------------------------------------------------------------------
- // RealShell::DispatchKeyDownEvent
- //-------------------------------------------------------------------------------------
- static ODBoolean EditFKeyDown( long message );
- static ODBoolean EditFKeyDown( long message )
- {
- if ( (message & charCodeMask) == 0x10 )
- {
- char keyCode = (message & keyCodeMask) >> 8;
- // aren't there constants for these keys anywhere?
- return (ODBoolean)(keyCode == 0x7A) || (keyCode == 0x78)
- || (keyCode ==0x63) || (keyCode == 0x76);
- }
- return kODFalse;
- }
-
- void RealShell::DispatchKeyDownEvent(ODEventData* event)
- {
- ODBoolean cmdKeyDown = (event->modifiers & cmdKey) != 0;
- ODBoolean optionKeyDown = (event->modifiers & optionKey) != 0;
- if ( cmdKeyDown || EditFKeyDown(event->message) ) // || F1, f2, f3, f4 were pressed
- this->UpdateMenus();
- // Fix #1221897
- // should also do update if function keys for Undo/Cut/Copy/Paste were pressed
-
- if ( !fDispatcher->Dispatch(fEV, event) )
- {
- if ( event->what == kODEvtMenu )
- this->HandleMenuCommand(event->message, event );
- else if ( cmdKeyDown && optionKeyDown )
- {
- // we have a command-key equivalent that didn't get recognized
- // because UI doesn't like the option key. So we need to change
- // the character to what it would be without the option, then get
- // the equivalent menu and invoke its handler with the additional
- // information that the option key was down.
-
- // Adapted from Finder code furnished by Greg Anderson
- unsigned char key = event->message & charCodeMask;
- short mangledKeyCode = (short)((event->message & keyCodeMask) >> 8)
- | (event->modifiers & keyCodeMask); // raw key w/ all modifiers
- UInt32 state = 0;
- Ptr kchrCache = (Ptr)GetScriptManagerVariable(smKCHRCache);
-
- // Find out if the raw key code matches the character in event.message.
- unsigned char computedKey = // only keep low byte
- (unsigned char)KeyTranslate( kchrCache, mangledKeyCode,
- &state );
-
- if (computedKey == key)
- {
- mangledKeyCode &= (0xFFFF - optionKey); // mask out option bit
- key = (unsigned char) KeyTranslate(kchrCache, mangledKeyCode, &state);
- // only keep low byte; we'll use this new keycode w/o option.
-
- // NOTE: I'm not changing the event, which HandleMenuCommand
- // ignores anyway.
- // ODBoolean oldOptionValue = fOptionKeyDownOnMenuBarClick;
- fOptionKeyDownOnMenuBarClick = kODTrue;
- this->HandleMenuCommand( MenuKey(key), event );
- // fOptionKeyDownOnMenuBarClick = oldOptionValue;
- }
- }
- }
- }
-
- //-------------------------------------------------------------------------------------
- // RealShell::HandleOSEvent
- //-------------------------------------------------------------------------------------
-
- void RealShell::HandleOSEvent(ODEventData* event)
- {
- // Is it a multifinder event?
- ODUByte typeOSEvent = (ODUByte) (event->message >> 24) & 0x00FF;
-
- // Switch on the type of OSEvent that occurred, high byte of message is event type
- switch (typeOSEvent)
- {
- case suspendResumeMessage:
- if( event->message & resumeFlag )
- this->ShowPendingNotifications(); // Display pending notifications
- else
- this->ExportClipboard(kODFalse);
- break;
- }
- }
-
- //-------------------------------------------------------------------------------------
- // RealShell::ExportClipboard
- //-------------------------------------------------------------------------------------
-
- void RealShell::ExportClipboard(ODBoolean canAlert)
- {
- ODClipboard* clipboard = fSession->GetClipboard(fEV);
-
- // TRY
- clipboard->ExportClipboard(fEV);
- // CATCH_ALL
- // if ( canAlert )
- // this->ExceptionAlert(ErrorCode(),ErrorMessage());
- // ENDTRY;
- }
-
- //-------------------------------------------------------------------------------------
- // Debug Menu Support
- //-------------------------------------------------------------------------------------
-
-
- #if ODDebugMenu
-
- #define SKIPOMPARSE
- #ifdef SKIPOMPARSE
- extern "C" {
- #endif
-
- #define kDumpTmpBufSize 3000
-
- static char gFilterNewClass;
- // gFilterNewClass is a global with a unique address passed to DumpObjProc as refCon
-
- static MMBoolean DumpObjProc( const void *blk, size_t size, MMBoolean isObject,
- void *refCon )
- {
- if( isObject ) {
- MMValidateObject((ODObject*)blk);
- somPrintf(" %p %4lu %s\r", blk,size, ((ODObject*)blk)->somGetClassName());
- }
- return true; // Might check for cmd-period or something to abort...
- }
-
- static void DumpBlockStackCrawl( const void *blk, size_t size, ODBoolean isObject,
- ODBoolean filter )
- {
- long flags = 0;
- StackCrawl* sc = MMGetBlockStackCrawl( blk, &flags );
- if (sc)
- {
- if ( !isObject )
- {
- somPrintf("%p %4lu:\r", blk, size);
- }
- static const char* kTooLongString = "... [too long]\n";
- char buffer[kDumpTmpBufSize + 32]; // add 32 for kTooLongString
- buffer[0] = 0;
- long numFrames = sc->CountFrames();
- long pos = 0;
- for (long i = 0; i < numFrames && pos < kDumpTmpBufSize; i++)
- {
- size_t offset;
- char tmpBuffer[256];
- char fnName[256];
- if (sc->LookupSymbol(i, fnName, &offset))
- {
- sprintf(tmpBuffer, "%s+%d\n", fnName, offset);
- long newPos = pos + strlen(tmpBuffer);
- if ( newPos < kDumpTmpBufSize )
- sprintf(&(buffer[pos]), "%s", tmpBuffer);
- else
- strcpy(&(buffer[pos]), kTooLongString);
-
- pos = newPos;
- }
- }
- if ( filter )
- {
- if ( buffer[0] && !strstr(buffer, "NewClass") )
- somPrintf("%s\r", buffer);
- }
- else
- {
- if ( buffer[0] )
- somPrintf("%s\r", buffer);
- }
- }
- }
-
- #ifdef SKIPOMPARSE
- }
- #endif
-
-
- struct TrackedBlockLink {
- TrackedBlockLink* fNext;
- const void* fFirstBlock;
- StackCrawl* fStack;
- unsigned long fCount;
- unsigned long fTotalSize;
- };
-
- static TrackedBlockLink* sTrackedBlockLinks;
-
- extern "C" {
- static MMBoolean
- FindObjsProc( const void *blk, size_t size, MMBoolean isObject, void *refCon )
- {
- long flags;
- StackCrawl* s = MMGetBlockStackCrawl(blk, &flags);
- if( s ) {
- size_t blockSize = MMBlockSize(blk);
-
- // This is a new block, check its stack crawl:
- TrackedBlockLink *l;
- for( l = sTrackedBlockLinks; l; l = l->fNext )
- if( *(l->fStack) == *s ) {
- l->fCount++;
- l->fTotalSize += blockSize;
- // delete s;
- // MMSetBlockStackCrawl(blk,kODNULL,0);
- return kODTrue;
- }
- l = new TrackedBlockLink;
- l->fNext = sTrackedBlockLinks;
- l->fFirstBlock = blk;
- l->fTotalSize = blockSize;
- l->fStack = s;
- l->fCount = 1;
- sTrackedBlockLinks = l;
- }
- return kODTrue;
- }
- }
-
- static void
- DumpFoundObjs()
- {
- unsigned long count = 0;
- unsigned long space = 0;
- TrackedBlockLink* next;
- ODBoolean filter = isFilterKeyDown();
-
- for( TrackedBlockLink * l = sTrackedBlockLinks; l; l = next ) {
- count += l->fCount;
- next = l->fNext;
- // if( l->fCount >= 3 ) {
- somPrintf("• Occurred %lu time%s, %lu total bytes:\r",
- l->fCount, (l->fCount == 1)? "": "s", l->fTotalSize);
- size_t size = MMBlockSize(l->fFirstBlock);
- ODBoolean isObject = MMIsObject(l->fFirstBlock);
-
- DumpObjProc(l->fFirstBlock, size, isObject, kODNULL);
- DumpBlockStackCrawl(l->fFirstBlock, size, isObject, filter);
-
- space += l->fTotalSize + (l->fCount * 8); // Add 8 bytes for per-block overhead
- // }
- delete l;
- }
- sTrackedBlockLinks = kODNULL;
- if( space > 0 )
- somPrintf("••• Estimated space in %lu tracked blocks: %lu bytes\r", count, space);
- else
- somPrintf("••• No tracked blocks found!\r");
- }
-
- static void
- DumpHeapObjects( ODBoolean objectsOnly )
- {
- const char *name;
- size_t allocated, free,blocks,objects;
- MMGetHeapInfo(kDefaultHeapID,
- &name, &allocated, &free, &blocks, &objects);
- somPrintf("••• Dump of %s •••\r%lu bytes allocated, %lu free (%.1f%% free).\r",
- name, (ODULong)allocated, (ODULong)free, 100.0*free/(float)(allocated+free) );
- somPrintf("There are %lu blocks, of which %lu are objects:\r", (ODULong)blocks, (ODULong)objects);
-
- if ( !objectsOnly && gTrackStackCrawls )
- {
- sTrackedBlockLinks = kODNULL;
-
- MMTrackStackCrawls(kODFalse); // disable stack crawls in FindObjsProc()
- MMWalkHeap(kDefaultHeapID, &FindObjsProc, kODNULL);
- DumpFoundObjs();
- MMTrackStackCrawls(kODTrue); // re-enable stack crawls
-
- sTrackedBlockLinks = kODNULL;
- }
- else
- {
- somPrintf(" ADDRESS SIZE CLASS\r");
- MMWalkHeap(kDefaultHeapID, &DumpObjProc, kODNULL);
- }
- }
-
-
- #endif
-
- //-------------------------------------------------------------------------------------
- // RealShell::HandleMenuCommand
- //-------------------------------------------------------------------------------------
-
-
- void RealShell::HandleMenuCommand(ODSLong menuResult, ODEventData* event)
- {
- ODUnused(event);
-
- ODSShort menu = HiWord(menuResult);
- ODSShort item = LoWord(menuResult);
- TempODMenuBar menuBar = fWindowState->AcquireCurrentMenuBar(fEV);
- ODCommandID command = menuBar->GetCommand(fEV,menu, item);
-
- if (menuBar->IsCommandSynthetic(fEV,command))
- {
- switch (menu)
- {
- case kODAppleMenuID: // Apple
- {
- Str255 daName;
- ODSShort daRefNum;
-
- GetMenuItemText(GetMenuHandle(kODAppleMenuID), item, daName);
- daRefNum = OpenDeskAcc(daName);
- HiliteMenu(0);
- break;
- }
-
- default:
- break;
- }
- }
- else
- {
- ODDraft* activeDraft = ODGetActiveDraft(fEV, fSession);
- ODDocument* activeDocument;
- if (activeDraft)
- activeDocument = activeDraft->GetDocument(fEV);
- else
- activeDocument = kODNULL;
-
- switch(command)
- {
- case kODCommandAbout: {
- CUsingLibraryResources r;
- ODSShort itemHit;
- GrafPtr savePort;
- GetPort(&savePort);
-
- fWindowState->DeactivateFrontWindows(fEV);
- TRY
- DialogPtr aboutDlg = ShowAboutScreen();
-
- ModalDialog(kODNULL /*modalFilter*/, &itemHit);
- if (aboutDlg)
- DisposeDialog(aboutDlg);
- CATCH_ALL
- fWindowState->ActivateFrontWindows(fEV);
- RERAISE;
- ENDTRY
- fWindowState->ActivateFrontWindows(fEV);
-
- SetPort(savePort);
- break;
- }
-
- // POSSIBLE FIX NEEDED: needs to use activeDocument?
- case kODCommandNew: delete (this->New()); break;
-
- case kODCommandOpenDocument: this->OpenStdFile(); break;
-
- case kODCommandClose:
- if (fOptionKeyDownOnMenuBarClick)
- {
- this->CloseDocument(activeDocument, kAEAsk);
- }
- else
- {
- WindowPtr platformWindow = kODNULL;
- {
- TempODWindow window = ODAcquireActiveWindow(fEV, fSession);
- if (window)
- platformWindow = window->GetPlatformWindow(fEV);
- }
- this->CloseWindow(platformWindow, kAEAsk);
- }
- break;
-
- case kODCommandDeleteDocument: this->DeleteDocument(activeDocument); break;
-
- case kODCommandSave: this->Save(activeDocument); break;
-
- case kODCommandSaveACopy: this->SaveACopy(activeDraft); break;
-
- case kODCommandRevert: this->Revert(activeDocument); break;
-
- case kODCommandDraft: this->Drafts(activeDocument); break;
-
- case kODCommandDocumentInfo: this->DocumentInfo(activeDocument); break;
-
- #ifdef SUPPORT_QUIT
- case kODCommandQuit: this->CloseAllDocs(kAEAsk); break;
- #endif
- case kODCommandUndo: fSession->GetUndo(fEV)->Undo(fEV); break;
-
- case kODCommandRedo: fSession->GetUndo(fEV)->Redo(fEV); break;
-
- // case kODCommandGetPartInfo: this->PartInfo(); break;
-
- #if ODDebugMenu
- case kODCommandDBHeapInfo: {
- HeapInfo();
- break;
- }
- case kODCommandDBDumpObjects:
- DumpHeapObjects( /*objectsOnly*/ kODTrue );
- break;
- case kODCommandDBDumpBlocks:
- DumpHeapObjects( /*objectsOnly*/ kODFalse );
- break;
- case kODCommandDBMemValidation:
- if( gMemValidation ) {
- if( gHeapChecking ) { // When turning off validation,
- MMEndHeapChecking(); // turn heap checking off too
- gHeapChecking = kODFalse;
- }
- MMEndMemValidation();
- gMemValidation = kODFalse;
- } else {
- MMBeginMemValidation();
- gMemValidation = kODTrue;
- }
- break;
- case kODCommandDBHeapChecking:
- if( gHeapChecking ) {
- MMEndHeapChecking();
- gHeapChecking = kODFalse;
- } else {
- MMBeginMemValidation(); // When turning on heap checking,
- gMemValidation = kODTrue; // turn validation on too
- MMBeginHeapChecking();
- gHeapChecking = kODTrue;
- }
- break;
- case kODCommandDBLeakChecking:
- if( gLeakChecking )
- MMEndLeakChecking();
- else
- MMBeginLeakChecking();
- gLeakChecking = !gLeakChecking;
- gTrackStackCrawls = gLeakChecking;
- break;
- case kODCommandDBDumpBlocksOnClose:
- gDumpBlocksOnClose = !gDumpBlocksOnClose;
- break;
- case kODCommandDBTrackStackCrawls:
- if( gTrackStackCrawls )
- MMTrackStackCrawls( kODFalse );
- else
- MMTrackStackCrawls( kODTrue );
- gTrackStackCrawls = !gTrackStackCrawls;
- break;
- case kODCommandDBEatMemory:
- (void) NewHandle(32*1024); // For testing low-mem survival!
- if( MemError() ) {
- SysBeep(3);
- WARN("Error %d eating memory!;ht",MemError());
- }
- break;
- case kODCommandDBPurge:
- this->Purge(10*1024*1024);
- break;
- case kODCommandDBLogStdout:
- if( GetOutputMode() != kWriteToFile )
- SetOutputMode(kWriteToFile);
- else
- SetOutputMode(kNoOutput);
- break;
- case kODCommandDBLogDebugWindow:
- if( GetOutputMode() != kWriteToDebugWindow )
- SetOutputMode(kWriteToDebugWindow);
- else
- SetOutputMode(kNoOutput);
- break;
- case kODCommandDBLogDebugStr:
- if( GetOutputMode() != kGenerateDebugStrs )
- SetOutputMode(kGenerateDebugStrs);
- else
- SetOutputMode(kNoOutput);
- break;
- case kODCommandDBBreakOnThrow:
- BreakOnThrow( ! BreakOnThrow(kODFalse) );
- // This looks weird, but we have to call it once to get the
- // old value, then again to set it to the opposite of that.
- break;
- case kODCommandDBSOMTrace:
- SOM_TraceLevel = !SOM_TraceLevel;
- break;
- #endif
-
- default:
- // some part enabled a menu command but did not handle it
- break;
- }
- HiliteMenu(0);
- }
- }
-
- //-------------------------------------------------------------------------------------
- // RealShell::HandleMouseDownInWindow
- //-------------------------------------------------------------------------------------
-
- void RealShell::HandleMouseDownInWindow(WindowPtr pwindow, ODSShort partCode, ODEventData* event)
- {
- switch (partCode)
- {
- case kODMDInGoAway:
- this->HandleMouseDownInCloseBox(pwindow, event);
- break;
-
- case kODMDInDrag:
- this->HandleMouseDownInDragRegion(pwindow, event);
- break;
-
- case kODMDInGrow:
- this->HandleMouseDownInGrowBox(pwindow, event);
- break;
-
- case kODMDInZoomIn:
- case kODMDInZoomOut:
- this->HandleMouseDownInZoomBox(pwindow, partCode,event);
- break;
-
- case kODMDInContent:
- {
- // This section used to select windows.
- // Parts must be responsible for window selection so that
- // the modal focus is respected.
- // Also, according to recipes, window selection should only
- // occur on mouse-up, anyway.
- TempODWindow window = fWindowState->AcquireODWindow(fEV,pwindow);
- if ( window != kODNULL )
- {
- if ( !window->IsActive( fEV ))
- {
- SysBeep( 2 );
- }
- //window->Select(fEV);
- }
- else if ( ((WindowPeek)pwindow)->hilited == kODFalse )
- {
- WARN("This window is not registered with OpenDoc!");
- SysBeep( 2 );
- //SelectWindow(pwindow);
- }
- }
- break;
- default:
- break;
- }
- }
-
- //-------------------------------------------------------------------------------------
- // RealShell::HandleMouseDownInCloseBox
- //-------------------------------------------------------------------------------------
-
- void RealShell::HandleMouseDownInCloseBox(WindowPtr pwindow, ODEventData* event)
- {
- if (TrackGoAway (pwindow, event->where))
- {
- if (IsOptionKeyDown())
- {
- ODDocument* document = kODNULL;
- {
- TempODWindow window = fWindowState->AcquireODWindow(fEV, pwindow);
- WASSERT(window != kODNULL);
- document = ODGetDraftOfWindow(fEV, window)->GetDocument(fEV);
- }
- this->CloseDocument(document, kAEAsk);
- }
- else
- this->CloseWindow(pwindow, kAEAsk);
- }
- }
-
- //-------------------------------------------------------------------------------------
- // RealShell::HandleMouseDownInDragRegion
- //-------------------------------------------------------------------------------------
-
- void RealShell::HandleMouseDownInDragRegion(WindowPtr platformWindow, ODEventData* event)
- {
- TempODWindow window = fWindowState->AcquireODWindow(fEV,platformWindow);
- if (window != kODNULL)
- {
- if ( window->IsActive( fEV ) || !this->IsSessionModal())
- window->Drag(fEV, &event->where, (Rect*)&ODQDGlobals.screenBits.bounds);
- else
- SysBeep( 2 );
- }
- else
- {
- if ( ((WindowPeek)platformWindow)->hilited || !this->IsSessionModal())
- {
- WARN("Dragging non-ODWindow.");
- DragWindow(platformWindow, event->where, &(ODQDGlobals.screenBits.bounds));
- }
- else
- SysBeep( 2 );
- }
-
- }
-
- //-------------------------------------------------------------------------------------
- // RealShell::HandleMouseDownInGrowBox
- //-------------------------------------------------------------------------------------
-
- void RealShell::HandleMouseDownInGrowBox(WindowPtr pwindow, ODEventData* event)
- {
- if (!fWindowState->IsODWindow(fEV,pwindow))
- return;
-
- TempODWindow window = fWindowState->AcquireODWindow(fEV,pwindow);
-
- if (window == kODNULL)
- return;
-
- if (window->IsResizable(fEV))
- {
- Rect growLimits; // = ODQDGlobals.screenBits.bounds);
-
- ODRgnHandle contRgn =
- ((WindowRecord*)(window->GetPlatformWindow(fEV)))->contRgn;
- Rect currentBounds = (**contRgn).rgnBBox;
-
- window->GetWindowBounds(fEV, ¤tBounds);
-
- growLimits.left = currentBounds.right-currentBounds.left;
- if (growLimits.left > kMinWindowWidth)
- growLimits.left = kMinWindowWidth;
- growLimits.top = currentBounds.bottom-currentBounds.top;
- if (growLimits.top > kMinWindowHeight)
- growLimits.top = kMinWindowHeight;
-
- growLimits.right = kMaxWindowWidth;
- growLimits.bottom = kMaxWindowHeight;
-
- ODSLong newWindowSize = GrowWindow(pwindow, event->where, &growLimits);
- SizeWindow(pwindow, LoWord(newWindowSize), HiWord(newWindowSize), true);
-
- window->AdjustWindowShape(fEV);
-
- Rect r = pwindow->portRect;
- r.left = r.right - 15;
- r.top = r.bottom - 15;
- RgnHandle oldClip = nil;
- GetClip(oldClip = ODNewRgn());
- ClipRect(&r);
- DrawGrowIcon(pwindow);
- SetClip(oldClip);
- ODDisposeHandle((Handle)oldClip);
- }
- }
-
- //-------------------------------------------------------------------------------------
- // RealShell::HandleMouseDownInZoomBox
- //-------------------------------------------------------------------------------------
-
- void RealShell::HandleMouseDownInZoomBox(WindowPtr pwindow, ODSShort partcode, ODEventData* event)
- {
- if (TrackBox(pwindow, event->where, partcode))
- {
- TempODWindow window = kODNULL;
-
- if (fWindowState->IsODWindow(fEV,pwindow))
- window = fWindowState->AcquireODWindow(fEV,pwindow);
-
- GrafPtr port;
- GetPort(&port);
- SetPort(pwindow);
-
- ZoomWindow(pwindow, partcode, kODFalse);
-
- SetPort(port);
-
- if (window)
- window->AdjustWindowShape(fEV);
- }
- }
-
- //-------------------------------------------------------------------------------------
- // RealShell::IsSessionModal
- //-------------------------------------------------------------------------------------
-
- ODBoolean RealShell::IsSessionModal()
- {
- TempODFrame modalFocus = fArbitrator->AcquireFocusOwner( fEV, fModalFocusToken );
- return modalFocus != kODNULL;
- }
-
- //-------------------------------------------------------------------------------------
- // RealShell::UpdateMenus
- //-------------------------------------------------------------------------------------
-
- void RealShell::UpdateMenus()
- {
- ODIText* menuItem;
- TempODMenuBar menuBar = fWindowState->AcquireCurrentMenuBar(fEV);
- MenuHandle appleMenu = menuBar->GetMenu(fEV, kODAppleMenuID);
- MenuHandle editMenu = menuBar->GetMenu(fEV, kODEditMenuID);
- ODDocument* activeDocument = ODGetActiveDocument(fEV, fSession);
-
- fOptionKeyDownOnMenuBarClick = IsOptionKeyDown();
-
- // Menu items which require resources:
- { CUsingLibraryResources r;
-
- // About Menu item
- this->RestoreMenuItem(appleMenu, kSHLMenuAbout, &fDefaultAboutMenuItem);
-
- //== Document-wide menu items
- Str255 targetName;
- if (activeDocument)
- {
- TempPlatformFile file =
- GetPlatformFileFromContainer(fEV, activeDocument->GetContainer(fEV));
-
- file->GetAsciiName( (char*)targetName, sizeof(targetName) );
- CToPascalString((char*)targetName);
- }
- else
- {
- targetName[0] = 0;
- }
- Str255 destString;
-
- // Delete Menu item
- ReplaceIntoString( kSHLDeleteItemTemplateStrID, targetName, kODNULL,
- destString );
- menuItem = CreateDefaultIText(destString);
- menuBar->SetItemString(fEV, kODCommandDeleteDocument, menuItem);
- DisposeIText(menuItem);
-
- // Save Menu item
- ReplaceIntoString( kSHLSaveItemTemplateStrID, targetName, kODNULL,
- destString );
- menuItem = CreateDefaultIText(destString);
- menuBar->SetItemString(fEV, kODCommandSave, menuItem);
- DisposeIText(menuItem);
-
- // Close Menu item
- if ( !IsOptionKeyDown() ) // close the whole document
- {
- TempODWindow window = ODAcquireActiveWindow(fEV, fSession);
- ODPlatformWindow pwin = window ?
- window->GetPlatformWindow(fEV) : kODNULL;
- if ( pwin )
- GetWTitle( pwin, targetName );
- else
- targetName[0] = '\0';
- }
-
- ReplaceIntoString( kSHLCloseItemTemplateStrID, targetName, kODNULL,
- destString );
- menuItem = CreateDefaultIText(destString);
- menuBar->SetItemString(fEV, kODCommandClose, menuItem);
- DisposeIText(menuItem);
-
- // Part Info menu item
- menuItem = GetODITextInd(kSHLStrsID, kSHLStrIndMPartInfo);
- menuBar->SetItemString(fEV, kODCommandGetPartInfo, menuItem);
- DisposeIText(menuItem);
- }
- menuBar->EnableCommand(fEV, kODCommandAbout, kODTrue);
- menuBar->EnableCommand(fEV, kODCommandClose, kODTrue);
- menuBar->EnableCommand(fEV, kODCommandGetPartInfo, kODFalse);
-
- // Document Menu
-
- menuBar->EnableCommand(fEV, kODCommandNew, kODTrue);
- menuBar->EnableCommand(fEV, kODCommandOpen, kODFalse);
- menuBar->EnableCommand(fEV, kODCommandOpenDocument, kODTrue);
- menuBar->EnableCommand(fEV, kODCommandInsert, kODFalse);
- menuBar->EnableCommand(fEV, kODCommandDeleteDocument,
- ODDocumentHasWriteAccess(fEV, fSession, activeDocument));
-
- ODBoolean unsavedChanges = ODDocumentHasChanges(fEV, fSession, activeDocument);
- menuBar->EnableCommand(fEV, kODCommandSave, unsavedChanges);
- menuBar->EnableCommand(fEV, kODCommandSaveACopy, kODTrue);
- menuBar->EnableCommand(fEV, kODCommandRevert, unsavedChanges);
-
- menuBar->EnableCommand(fEV, kODCommandDraft, kODTrue);
- menuBar->EnableCommand(fEV, kODCommandDocumentInfo, kODTrue);
- menuBar->EnableCommand(fEV, kODCommandPageSetup, kODFalse);
- menuBar->EnableCommand(fEV, kODCommandPrint, kODFalse);
-
- #ifdef SUPPORT_QUIT
- if( fAPPLProcess )
- menuBar->EnableCommand(fEV, kODCommandQuit, kODTrue);
- #endif
-
- // Edit Menu
-
- this->UpdateUndoMenus();
-
- menuBar->EnableCommand(fEV, kODCommandCut, kODFalse);
- menuBar->EnableCommand(fEV, kODCommandCopy, kODFalse);
- menuBar->EnableCommand(fEV, kODCommandPaste, kODFalse);
- menuBar->EnableCommand(fEV, kODCommandPasteAs, kODFalse);
- menuBar->EnableCommand(fEV, kODCommandClear, kODFalse);
- menuBar->EnableCommand(fEV, kODCommandSelectAll, kODFalse);
-
- menuBar->EnableCommand(fEV, kODCommandPreferences , kODFalse);
- menuBar->EnableCommand(fEV, kODCommandViewAsWin, kODFalse);
-
- if ( editMenu )
- this->RestoreMenuItem(editMenu, kSHLMenuPreferences, &fDefaultPrefsMenuItem);
-
- #if ODDebugMenu
- DebugOutputMode outMode = GetOutputMode();
- ODBoolean breakingOnThrow = BreakOnThrow(kODFalse);
- BreakOnThrow(breakingOnThrow); // Have to reset original value...
- menuBar->EnableCommand(fEV, kODCommandDBDumpObjects, outMode!=kNoOutput);
- menuBar->EnableCommand(fEV, kODCommandDBDumpBlocks, gTrackStackCrawls>0 && outMode!=kNoOutput);
- menuBar->CheckCommand(fEV, kODCommandDBMemValidation, gMemValidation>0);
- menuBar->CheckCommand(fEV, kODCommandDBHeapChecking, gHeapChecking>0);
- menuBar->EnableCommand(fEV, kODCommandDBLeakChecking, outMode!=kNoOutput);
- menuBar->CheckCommand(fEV, kODCommandDBLeakChecking, gLeakChecking>0);
- menuBar->EnableCommand(fEV, kODCommandDBDumpBlocksOnClose, outMode!=kNoOutput);
- menuBar->CheckCommand(fEV, kODCommandDBDumpBlocksOnClose, gDumpBlocksOnClose>0);
- menuBar->EnableCommand(fEV, kODCommandDBTrackStackCrawls, kODTrue);
- menuBar->CheckCommand(fEV, kODCommandDBTrackStackCrawls, gTrackStackCrawls>0);
- menuBar->CheckCommand(fEV, kODCommandDBLogStdout, outMode==kWriteToFile);
- menuBar->CheckCommand(fEV, kODCommandDBLogDebugWindow, outMode==kWriteToDebugWindow);
- menuBar->CheckCommand(fEV, kODCommandDBLogDebugStr, outMode==kGenerateDebugStrs);
- menuBar->CheckCommand(fEV, kODCommandDBBreakOnThrow, breakingOnThrow);
- menuBar->CheckCommand(fEV, kODCommandDBSOMTrace, SOM_TraceLevel!=0);
- #endif
-
- // Let the parts have the last crack at the menus.
- fWindowState->AdjustPartMenus(fEV);
- }
-
- //------------------------------------------------------------------------------
- // RealShell::CheckMenuBar
- //------------------------------------------------------------------------------
-
- void RealShell::CheckMenuBar()
- {
- ODBoolean shellHadMenuFocus = fShellHasMenuFocus;
- ODTypeToken menuFocus = fSession->Tokenize(fEV, kODMenuFocus);
- TempODFrame focusFrame = fSession->GetArbitrator(fEV)->AcquireFocusOwner(fEV, menuFocus);
- fShellHasMenuFocus = (focusFrame == kODNULL);
-
- if (fShellHasMenuFocus && !shellHadMenuFocus)
- {
- TempODMenuBar baseMenuBar = fWindowState->AcquireBaseMenuBar(fEV);
- if (baseMenuBar)
- baseMenuBar->Display(fEV);
- }
- }
-
- //------------------------------------------------------------------------------
- // RealShell::UpdateUndoMenus
- //------------------------------------------------------------------------------
-
- void RealShell::UpdateUndoMenus()
- {
- ODUndo* undo = fSession->GetUndo(fEV);
- ODPart* part;
- ODActionData actionData;
- ODActionType actionType;
- ODName actionLabel;
-
- ODVolatile(actionLabel);
- ODVolatile(actionData);
-
- actionLabel.text._buffer = kODNULL;
- actionData._buffer = kODNULL;
-
- TRY
- TempODMenuBar menuBar = fWindowState->AcquireCurrentMenuBar(fEV);
- MenuHandle editMenu = menuBar->GetMenu(fEV, kODEditMenuID);
-
- // these IsCommandRegistered calls are to prevent ResetUndoText from
- // being called with a null menu, which is what you get at least
- // in the EditorSetup case. Other cases might not be detected
-
- if (undo->PeekUndoHistory(fEV, &part, &actionData, &actionType,
- &actionLabel))
- {
- menuBar->EnableCommand(fEV, kODCommandUndo, kODTrue);
- menuBar->SetItemString(fEV, kODCommandUndo, &actionLabel);
- }
- else
- {
- menuBar->EnableCommand(fEV, kODCommandUndo, kODFalse);
- this->ResetUndoText(editMenu);
- }
-
- DisposeITextStruct(actionLabel);
- DisposeByteArrayStruct(actionData);
- actionLabel.text._buffer = kODNULL;
- actionData._buffer = kODNULL;
-
- if (undo->PeekRedoHistory(fEV, &part, &actionData, &actionType,
- &actionLabel))
- {
- menuBar->EnableCommand(fEV, kODCommandRedo, kODTrue);
- menuBar->SetItemString(fEV, kODCommandRedo, &actionLabel);
- }
- else
- {
- menuBar->EnableCommand(fEV, kODCommandRedo, kODFalse);
- this->ResetRedoText(editMenu);
- }
- CATCH_ALL
- if (actionLabel.text._buffer)
- DisposeITextStruct(actionLabel);
- if (actionData._buffer)
- DisposeByteArrayStruct(actionData);
- RERAISE;
- ENDTRY
-
- DisposeITextStruct(actionLabel);
- DisposeByteArrayStruct(actionData);
- }
-
-
- //-------------------------------------------------------------------------------------
- // RealShell::ResetUndoText
- //-------------------------------------------------------------------------------------
-
- void RealShell::ResetUndoText(MenuHandle editMenu)
- {
- if ( editMenu )
- this->RestoreMenuItem(editMenu, kSHLMenuUndo, &fDefaultUndoMenuItem);
- }
-
- //-------------------------------------------------------------------------------------
- // RealShell::ResetRedoText
- //-------------------------------------------------------------------------------------
-
- void RealShell::ResetRedoText(MenuHandle editMenu)
- {
- if ( editMenu )
- this->RestoreMenuItem(editMenu, kSHLMenuRedo, &fDefaultRedoMenuItem);
- }
-
- //-------------------------------------------------------------------------------------
- // New
- //-------------------------------------------------------------------------------------
-
- PlatformFile* RealShell::New()
- {
- // create another container, create a root part of the same kind and editor
- // as the root part of the active window
-
- TempODType rootPartType = kODNULL;
- TempODEditor editor = kODNULL;
- TempODName category = kODNULL;
- ODStorageUnit* psu = kODNULL;
- PlatformFile* newFile = new PlatformFile();
-
- TempODWindow window = ODAcquireActiveWindow(fEV, fSession);
- if (window)
- {
- TempODPart part = window->GetRootFrame(fEV)->AcquirePart(fEV);
- ASSERT((ODPart*)part != kODNULL, kODErrNoDraftProperties);
- // !!!!! Should probably have its own errorcode, even though the user
- // error message will be the same.
- category = ODGetCategory(fEV, part, fSession->GetNameSpaceManager(fEV));
- psu = part->GetStorageUnit(fEV);
- }
-
- if (psu &&
- psu->Exists(fEV, kODPropContents, (ODValueType)kODNULL, (ODValueIndex)kODNULL))
- {
- psu->Focus(fEV, kODPropContents, kODPosSame, (ODValueType)kODNULL,1, kODPosFirstSib);
- rootPartType = psu->GetType(fEV);
- editor = (ODEditor)ODGetISOStrProp(fEV, psu, kODPropPreferredEditor, kODEditor, kODNULL, kODNULL);
-
- TempPlatformFile file = GetPlatformFileFromContainer(fEV,
- psu->GetDraft(fEV)->GetDocument(fEV)->GetContainer(fEV));
- newFile->SpecifyFromFile(file);
- }
-
- {
- ODContainer* container;
- CreateUntitledContainer(kODNULL, &container, newFile, category);
- TempODContainer newContainer = container;
- ODNewDocument(fEV, newContainer, rootPartType, editor);
- }
-
- if( fAPPLProcess )
- this->OpenFile(newFile);
- else
- this->OpenAnotherFile(newFile, kODNULL, kODTrue, kODTrue); // Both are true because this is a new unsaved doc
- return newFile;
- }
-
- //-------------------------------------------------------------------------------------
- // New File(Name/Spec)
- //-------------------------------------------------------------------------------------
-
- ODStatic void CreateNewUntitledFile(PlatformFile* newFile,
- char* fileNameSeed)
- {
- Str255 fileName; // !!!! MUST BE AN ARRAY IN ORDER TO WORK (sizeof used below)
-
- if (newFile->IsStationery())
- {
- newFile->GetAsciiName((char*)fileName, sizeof(fileName)-1);
- }
- else if (fileNameSeed != kODNULL)
- {
- strncpy((char*)fileName, fileNameSeed, sizeof(fileName)-1);
- }
- else
- {
- strcpy((char*)fileName, "");
- }
-
- CToPascalString((char*)fileName);
- if ( fileName[0] > kODMaxFileNameSize )
- (void)ClipStringToBytes( fileName, kODMaxFileNameSize, smSystemScript );
- PascalToCString(fileName);
-
- newFile->SetAsciiName((char*)fileName);
-
- CreateNewFile(newFile, kODForceNewName);
- }
-
- void CreateNewFile(PlatformFile* newFile, ODBoolean forceNewName)
- {
- ODSLong seed = 0;
- ODULong err = noErr;
-
- ODSByte prefixName[kODMaxFileNameSize+1];
- newFile->GetAsciiName(prefixName, kODMaxFileNameSize);
- prefixName[kODMaxFileNameSize] = 0;
- ODUShort prefixLen = strlen(prefixName);
-
- ODSByte newName[kODMaxFileNameSize+1];
- strcpy(newName,prefixName);
-
- ODFileSpec fs = newFile->GetFileSpec();
-
- while (GetVolumeWritableSpace(&fs, kODNULL) < kSpaceNeededForNewDocument)
- {
-
- THROW_IF_ERROR(FindFolder(kOnSystemDisk, kDesktopFolderType, kCreateFolder,
- &(fs.vRefNum), &(fs.parID)));
-
- if (GetVolumeWritableSpace(&fs, &err) >= kSpaceNeededForNewDocument)
- break;
-
- THROW_IF_ERROR(err);
- THROW(kODErrSystemVolumeIsFull);
-
- // It would be nice to try other volumes as well, like:
- // iterate through local non-removable volumes
- // if enough space on one of those, then use it & break; break;
- // iterate through local removable volumes
- // if enough space on one of those, then use it & break; break;
- // iterate through remote volumes
- // if enough space on one of those, then use it & break; break;
-
- // THROW(kODErrAllWritableVolumesAreFull);
-
- }
- newFile->Specify(&fs);
- newFile->UniquifyName( kODNoResourceID /*kConcatDefaultNameNoNumStrID*/, kODNULL,
- kSHLNewFilenameTemplateStrID, kODNULL, 1, kSpecifyNewNameOnly, forceNewName );
-
- } // CreateNewFile
-
- void RealShell::CreateUntitledContainer(ODDocument** documentPtr,
- ODContainer** containerPtr, PlatformFile* newFile, ODName* fileNameSeed)
- {
- char* cfnSeed = kODNULL;
- if (fileNameSeed != kODNULL)
- cfnSeed = GetITextCString(fileNameSeed, kODNULL);
-
- CreateNewUntitledFile(newFile, cfnSeed);
-
- ODDeleteObject(cfnSeed);
-
- newFile->Create(kODShellSignature, kODShellSignature, 0);
-
- ODULong refNumCount;
- ODSShort* refNums;
- if (documentPtr)
- {
- GetLocalPaths(&(newFile->GetFileSpec()), kDataFork,
- &refNumCount, &refNums);
- }
-
- (*containerPtr) = CreateFileContainer(fEV, fSession, &(newFile->GetFileSpec()));
-
- if (documentPtr)
- {
- *documentPtr = (*containerPtr)->AcquireDocument(fEV, kODDefaultDocument); // -- TÇ: documentPtr acquires a document
- }
- }
-
- void RealShell::CreateTitledContainer(ODDocument** documentPtr,
- ODContainer** containerPtr, PlatformFile* newFile, char* newName)
- {
- newFile->SetAsciiName(newName);
-
- CreateNewFile(newFile, kODTryCurrentName);
-
- newFile->Create(kODShellSignature, kODShellSignature, 0);
-
- ODULong refNumCount;
- ODSShort* refNums;
- if (documentPtr)
- {
- GetLocalPaths(&(newFile->GetFileSpec()), kDataFork,
- &refNumCount, &refNums);
- }
-
- (*containerPtr) = CreateFileContainer(fEV, fSession, &(newFile->GetFileSpec()));
-
- if (documentPtr)
- {
- *documentPtr = (*containerPtr)->AcquireDocument(fEV, kODDefaultDocument); // -- TÇ: documentPtr acquires a document
- }
- }
-
- //------------------------------------------------------------------------------
- // Temporary File(Name/Spec)
- //------------------------------------------------------------------------------
-
- void CreateTempName(short seed, Str255 name, ODBoolean isFile)
- {
- // Don't modify this one!
- char* nmSeed = isFile? "ODShellTempFile" : "ODShellTempFolder";
- strcpy((char*)name, nmSeed);
-
- char theNum[10];
- NumToString(seed, (StringPtr)theNum);
- WASSERT(theNum[0] <= 5);
- p2cstr((StringPtr)theNum);
-
- strcat((char*)name, theNum);
- c2pstr((char *)name);
- }
-
-
- void RealShell::CreateUniqueTmpFolderForFile(ODFileSpec* result,
- Str63 fileName)
- {
- Str255 myName;
- ODSLong myDirID;
- ODSShort myVRef;
- GetTempFolder(&myVRef, &myDirID);
-
- OSErr err;
- short limit = kMaxUniqueNameTries;
- while ( --limit )
- {
- CreateTempName( fUniqueNameSeed++, myName, kODFalse );
- long createdDirID;
- err = DirCreate( myVRef, myDirID, myName,
- &createdDirID );
- if ( err == noErr )
- {
- FSMakeFSSpec(myVRef, createdDirID, fileName, result);
- return;
- }
- }
- THROW( err );
- }
-
- void GetTempFolder(ODSShort* VRef,ODSLong* DirID)
- {
- FindFolder(0, kTemporaryFolderType, kCreateFolder,VRef,DirID);
- }
-
- //-------------------------------------------------------------------------------------
- // CopyResources -- copy the document resources from one file to another
- //-------------------------------------------------------------------------------------
-
- ODStatic void CopyResources(PlatformFile* srcFile, PlatformFile* dstFile)
- {
- CUsingLibraryResources r;
- VerifyDocumentStub(&(dstFile->GetFileSpec()), kODNULL);
- // Makes sure to copy resources into the new document.
-
- ODULong sizeOfResource;
- for(ODUShort i=0; i<= 1; i++) {
- ODPtr sizeRes = srcFile->ReadResourcePtr(kSIZERsrcType, i, &sizeOfResource);
- if (sizeRes != kODNULL) {
- dstFile->WriteResourcePtr(kSIZERsrcType, i, sizeRes, sizeOfResource);
- ODDisposePtr(sizeRes);
- }
- }
- }
-
- //-------------------------------------------------------------------------------------
- // Open
- //-------------------------------------------------------------------------------------
-
- ODDocument*
- RealShell::OpenFile(PlatformFile* file, ODBoolean forceOpenApp /*=false*/)
- {
- // if the file is a stationery seed,
- // produce mature stationery in the Stationery folder and quit
- // else create a new container if the given file is stationery
- // else open the container and document and current draft and install ShellPlugIns
- // note: file is not consumed and is presumed to be disposed of by the caller
-
- // 'forceOpenApp' is true when an app containing a document is being launched.
- // (The 'oapp' handler will set this to true.) If so we should assume that this
- // is an OpenDoc document regardless of its filetype, and open it read-only.
-
- WatchCursor();
- ODPlatformType fileType = file->GetPlatformType();
-
- ODFileSpec fs = file->GetFileSpec();
-
- // ASSERT(the document is at the end of the resource chain)
-
- ODSShort numSeeds = Count1Resources(kDocSeedResType);
- if (numSeeds > 0)
- {
- FindStationeryFolder(&(fs.vRefNum), &(fs.parID));
- file->Specify(&fs);
-
- for (;numSeeds;--numSeeds)
- {
- Handle seedEditor;
- ODContainer* container;
- short unusedID;
- ResType unusedType;
- Str255 editorName;
-
- seedEditor = Get1IndResource(kDocSeedResType, numSeeds);
- TempODType editor = (ODType)ODNewPtr(GetHandleSize(seedEditor),0);//•minor leak [FIXED]
- HLock(seedEditor); //• unnecessary; CFM libs have no segments
- strcpy((char*)editor, (char*)*seedEditor);
- HUnlock(seedEditor);
- GetResInfo(seedEditor, &unusedID, &unusedType, editorName);
- if (editorName[0] > 31)
- ClipStringToBytes( editorName, 31, smCurrentScript );
- PascalToCString(editorName);
- CreateTitledContainer(kODNULL, &container, file, (char*)editorName);//•minor leak on exception [FIXED]
- TempODContainer tempContainer = container; // ensures it's released
-
- ODNewDocument(fEV, tempContainer, kODNULL, editor);
- TempODDocument newDocument = tempContainer->AcquireDocument(fEV, kODDefaultDocument);
- TempODDraft newDraft = newDocument->AcquireBaseDraft(fEV, kODDPExclusiveWrite);
- ODClearIsUnsavedNewDocument(fEV, newDraft);
- newDraft->Externalize(fEV);
- file->SetStationery(kODTrue);
-
- RemoveResource(seedEditor);
- }
-
- UpdateResFile(CurResFile());
- fDispatcher->Exit(fEV);
- return kODNULL; // Didn't open any document
- }
- else
- {
- PlatformFile* newFile = kODNULL;
- ODVolatile(newFile);
- if (file->IsOpenDocDocument())
- {
- if (file->IsStationery())
- {
- TRY
- ODContainer* container = kODNULL;
- ODDocument* document = kODNULL;
- ODDraft* draft = kODNULL;
- ODAcquireCtrDocTopDraft(fEV, fSession, file, &container, &document, &draft);
- TempODContainer sContainer = container;
- TempODDocument sDocument = document;
- TempODDraft sDraft = draft;
-
- newFile = new PlatformFile;
- newFile->SpecifyFromFile(file);
-
- container = kODNULL; document = kODNULL;
- CreateUntitledContainer(&document, &container, newFile);
- TempODContainer newContainer = container;
- TempODDocument newDocument = document;
-
- CopyResources(file, newFile);
- newDocument->SetBaseDraftFromForeignDraft(fEV, sDraft);
- TempODDraft newDraft = newDocument->AcquireBaseDraft(fEV, kODDPExclusiveWrite);
- {
- TempODStorageUnit su = newDraft->AcquireDraftProperties(fEV);
- ODResetDateModByInfo(fEV, su);
- }
- {
- TempODStorageUnit su = ODAcquireRootPartSUOfDraft(fEV, newDraft);
- ODResetDateModByInfo(fEV, su);
- }
- ODSetIsUnsavedNewDocument(fEV, newDraft);
- newDraft->Externalize(fEV);
-
- newFile->SetPlatformType(file->GetPlatformType());
- newFile->SetPlatformCreator(file->GetPlatformCreator());
-
- { TempODDocumentName name(newFile->GetName());
- newDocument->SetName(fEV, name);
- }
-
- file = newFile;
- CATCH_ALL
- if (newFile)
- {
- TRY
- newFile->MoveToTrash();
- CATCH_ALL
- ENDTRY
- }
- RERAISE;
- ENDTRY
- }
-
- }
- else if( !forceOpenApp )
- {
- // translate fileType into an OpenDoc kind
- TempODType theKind = fSession->GetTranslation(fEV)->
- GetISOTypeFromPlatformType(fEV, fileType, kODPlatformFileType);
-
- // Check to see if fileType is supported by an OpenDoc Editor
- ODEditor theEditor = fSession->GetBinding(fEV)->ChooseEditorForPart( fEV, kODNULL, theKind );
- if (!theEditor)
- {
- fDispatcher->Exit(fEV);
- THROW( kODErrCouldNotBindForeignDocument );
- }
-
- // create new File
- newFile = new PlatformFile(); //• leak on exception
- newFile->SpecifyFromFile(file);
- Str255 fileName;
- Str255 newName;
- newFile->GetAsciiName( (char*)fileName, kODMaxFileNameSize );
- CToPascalString((char*)fileName);
- { CUsingLibraryResources r;
- ReplaceIntoString(kSHLPreODDocNameStrID, fileName,
- kODEmptyPString, newName);
- }
- PascalToCString(newName);
-
- // Need actual object pointers because of CreateTitledContainer calling conventions
- ODDocument* document = kODNULL;
- ODContainer* container = kODNULL;
-
- CreateTitledContainer(&document, &container, newFile, (char*)newName);
- // Now immediately assign to tempobj's to be exception safe.
- TempODContainer newContainer = container;
- TempODDocument newDocument = document;
-
- HFSFlavor hfsFlavor;
- hfsFlavor.fileType = fileType;
- hfsFlavor.fileCreator = file->GetPlatformCreator();
- hfsFlavor.fdFlags = file->GetFInfoFlags();
- hfsFlavor.fileSpec = file->GetFileSpec();
-
- ((ODUByte*)(&fileType))[0] = kODPlatformKindFileChar1;
- newFile->SetPlatformType(fileType);
-
- TempODDraft newDraft = newDocument->AcquireBaseDraft(fEV, kODDPExclusiveWrite);
- TempODStorageUnit su = newDraft->AcquireDraftProperties(fEV);
- ODResetDateModByInfo(fEV, su);
-
- TempODStorageUnit rootPartSU = newDraft->CreateStorageUnit(fEV);
- ODSetRootPartSUOfDraft(fEV, newDraft, rootPartSU);
-
- // create contents prop/ value for kODApplehfs
- ODSUAddPropValue(fEV, rootPartSU, kODPropContents, kODApplehfs);
- StorageUnitSetValue(rootPartSU, fEV, sizeof( hfsFlavor ), &hfsFlavor);
- rootPartSU->AddValue(fEV, theKind);
-
- ODSetISOStrProp(fEV, rootPartSU, kODPropPreferredEditor, kODEditor, theEditor);
-
- ODSetIsUnsavedNewDocument(fEV, newDraft);
- newDraft->Externalize(fEV);
- file = newFile;
- }
-
- ODDocument *document;
- ODDraft* topdraft = kODNULL;
- ODVolatile(topdraft);
-
- TRY
- // Open the document
- TRY
- topdraft = ODOpenFileDocument(fEV, fSession, file,
- forceOpenApp ?kODDPReadOnly :kODDPExclusiveWrite);
- this->InstallShellPlugIns(topdraft);
-
- ODOpenDraft(fEV, fSession, topdraft);
- CATCH_ALL
- // Expanding the set of messages users get when something goes really
- // wrong opening a draft. As DH says, if you see this you need to
- // fix something right away. NOTE: this code should be here for a
- // *very* short time!
- if ( ErrorCode() == kODErrBentoInvalidProperty ) // (should be kODErrBentoErr)
- ODShellCorruptDocGoodbye();
- else if (( ErrorCode() == -108) || (ErrorCode() == kODErrOutOfMemory) )
- //$$$$$ - dh
- //This is a VERY TEMPORARY fix for our crashing problems when
- //there are problems opening a document. If you see this, alert the
- //authorities and immediately work on getting rid of it!!!
- ODShellLowMemoryGoodbye();
- else
- ODShellGenericGoodbye( ErrorCode() != kODErrAlreadyNotified );
- ENDTRY
- document = topdraft->GetDocument(fEV);
- ODReleaseObject(fEV, topdraft);
-
- fDispatcher = fSession->GetDispatcher(fEV);
- fWindowState = fSession->GetWindowState(fEV);
- fArbitrator = fSession->GetArbitrator( fEV );
-
- ODFileSpec fileFSSpec = file->GetFileSpec();
-
- LMSetSFSaveDisk(-(fileFSSpec.vRefNum));
- LMSetCurDirStore(fileFSSpec.parID);
- ODDeleteObject(newFile);
- CATCH_ALL
- this->CheckFreeMemory();
- if (topdraft)
- {
- ODDocument* document = topdraft->GetDocument(fEV);
- ODSafeReleaseObject(topdraft);
- if (ODCloseDocument(fEV, fSession, document))
- fDispatcher->Exit(fEV);
- }
- this->SetAEError(ErrorCode());
- ENDTRY
- ArrowCursor();
-
- return document;
- }
- } // RealShell::OpenFile
-
- //------------------------------------------------------------------------------
- // RealShell::OpenAnotherFile
- //------------------------------------------------------------------------------
-
- void RealShell::OpenAnotherFile(PlatformFile* file,
- AEDescList* replyInfo,
- ODBoolean deleteOnFailure,
- ODBoolean unsavedDoc)
- {
- // launch another document stub to open the passed in PlatformFile
- OSErr err = noErr;
- ODFileSpec theDocument = file->GetFileSpec();
- if (WasLaunchedThenActivate(&theDocument, kAEOpenDocuments, err))
- return;
-
- ODSLong savedRefNum;
- BeginUsingLibraryResources(savedRefNum);
- AEDesc docDesc;
- ProcessSerialNumber psn;
- err = AECreateDesc( typeFSS, &theDocument, sizeof(theDocument),
- &docDesc );
- if ( !err )
- {
- err = VerifyAndLaunchDocumentStub(&docDesc, replyInfo, &psn,
- kAEOpenDocuments, kODNULL, unsavedDoc);
- AEDisposeDesc( &docDesc );
- }
- EndUsingLibraryResources(savedRefNum);
- if ( err ) {
- if( deleteOnFailure )
- file->Delete();
- THROW( err );
- } else if( deleteOnFailure ) {
- // Remember PSN and spec in case launch fails; CFM will send us an error and
- // we can then delete the new file. See HandleLaunchFailedEvent...
- fLastNewDocPSN = psn;
- fLastNewDocSpec= file->GetFileSpec();
- }
- }
-
- //------------------------------------------------------------------------------
- // OpenFileFilter
- //
- // Return true (don't show this item) for invisible files and folders
- //
- // Addendum: There appears to be no way to filter out invisible folders, since
- // thie function is only passed files. Oh well. Leaving code in anyway in case
- // this changes.
- //------------------------------------------------------------------------------
-
- static pascal Boolean OpenFileFilter(CInfoPBPtr fileInfo)
- {
- if (fileInfo->hFileInfo.ioFlAttrib & ioDirMask) // FOLDER
- {
- if (fileInfo->dirInfo.ioDrUsrWds.frFlags & fInvisible)
- return true;
- }
- else // FILE
- {
- if (fileInfo->hFileInfo.ioFlFndrInfo.fdFlags & fInvisible)
- return true;
- }
-
- return false;
- }
-
- //------------------------------------------------------------------------------
- // RealShell::OpenStdFile
- //------------------------------------------------------------------------------
-
- void RealShell::OpenStdFile()
- {
- // call display StdFile (with all documents) and open document in a new shell
- ArrowCursor();
- StandardFileReply sfReply;
- SFTypeList sfTypes;
-
- fWindowState->DeactivateFrontWindows(fEV);
-
- FileFilterUPP openFileFilterUPP = NewFileFilterProc(OpenFileFilter);
- StandardGetFile((FileFilterUPP)openFileFilterUPP, -1, sfTypes, &sfReply);
- DisposeRoutineDescriptor(openFileFilterUPP);
-
- fWindowState->ActivateFrontWindows(fEV);
-
- if (sfReply.sfGood)
- {
- TempPlatformFile file = new PlatformFile();
- file->Specify(&sfReply.sfFile);
- if( ! file->IsOpenDocDocument() )
- {
- THROW_IF_ERROR( SendFinderODOCEvent( &sfReply.sfFile ) );
-
- // Fix #1221901:
- // else (if creator≠ kODShellSignature)
- // 'appl' = launch application
- // else 'snd ' = play sound
- // else 'cdev' = open control panel
- // else use MEO,desktop database to find appropriate application to use,
- // then launch application with document
- } else {
- // Open document in this process if I am an application process
- // with the same signature as the doc; e.g. CyberDog.
- // Otherwise launch doc into a new OD process.
- ProcessInfoRec info;
- GetCurrentProcessInfo(&info);
- if( info.processType=='APPL' && info.processSignature==file->GetPlatformCreator() )
- this->OpenFile(file);
- else
- this->OpenAnotherFile(file);
- }
- }
- }
-
- //-------------------------------------------------------------------------------------
- // DoesUserCancelClose
- //
- // To do: Fix flow of control
- //-------------------------------------------------------------------------------------
-
- ODBoolean RealShell::DoesUserCancelClose(ODDocument* document, DescType saveOptions)
- {
- // asks user "Save changes before closing? Discard Changes, Cancel , Save"
- ODBoolean stillSave;
- switch(saveOptions)
- {
- case kAEAsk:
- {
- if (AEInteractWithUser(kNoTimeOut, NULL, NULL) != noErr)
- return kODTrue;
- ArrowCursor();
- char fileName[256];
- ODGetDocumentFileName(fEV, document, &(fileName[0]));
- CToPascalString(fileName);
-
-
- ODSShort btnClicked;
- if (ODIsTempDocument(fEV, fSession, document))
- {
- if (ODIsUnsavedNewDocument(fEV, fSession, document))
- btnClicked = kSHLscNo;
- else
- btnClicked = kSHLscOK;
- }
- else
- {
- ODSLong savedRefNum;
- BeginUsingLibraryResources(savedRefNum);
- ParamText((unsigned char const *)fileName, kODEmptyPString,
- kODEmptyPString, kODEmptyPString);
- fWindowState->DeactivateFrontWindows(fEV);
- TRY
- {
- DialogPtr askSaveDlg = kODNULL;
- askSaveDlg = ODGetNewDialog( fEV, kSHLsvChanges, fSession, kODTrue );
- THROW_IF_NULL( askSaveDlg );
- ODUseCommandKeyStringsResource( kSHLsvChangesCmdKeyStrs );
- ::ShowWindow( askSaveDlg );
- // FIX_THIS_PLACE
- ::ModalDialog( GetODButtonKeyFilterProc(), &btnClicked );
- ::DisposeDialog( askSaveDlg );
- }
- CATCH_ALL
- {
- btnClicked = kSHLscCancel; // Cancel the close
- }
- ENDTRY
-
- fWindowState->ActivateFrontWindows(fEV);
-
- EndUsingLibraryResources(savedRefNum);
- }
- if (btnClicked == kSHLscCancel)
- return kODTrue;
- else if (btnClicked == kSHLscNo &&
- ODIsUnsavedNewDocument(fEV, fSession, document))
- {
- TempPlatformFile file =
- GetPlatformFileFromContainer(fEV, document->GetContainer(fEV));
- file->MoveToTrash();
- }
-
- stillSave = (btnClicked == kSHLscOK);
- }
- break;
- case kAEYes:
- stillSave = kODTrue;
- break;
- case kAENo:
- stillSave = kODFalse;
- break;
- default:
- THROW(errAETypeError);
- }
-
- if (stillSave)
- {
- if (this->Save(document, kODTrue, saveOptions))
- ;
- else // The user canceled the Save As dialog, which cancels the close
- return kODTrue;
- }
- return kODFalse;
- }
-
-
- void RealShell::CloseWindow(ODPlatformWindow pwindow, DescType saveOptions)
- {
- if (pwindow==kODNULL)
- {
- fDispatcher->Exit(fEV);
- return;
- }
-
- if (!fWindowState->IsODWindow(fEV,pwindow))
- {
- ASSERT(fWindowState->IsODWindow(fEV,pwindow), kODErrClosingNonODWindow);
- return;
- }
-
- ODWindow* window = fWindowState->AcquireODWindow(fEV,pwindow);
- if (!window)
- return;
-
- ODDraft* draft = window->GetDraft(fEV);
- ODDocument* document = draft->GetDocument(fEV);
- ODBoolean isOnlyTopDraftWindow =
- window->IsRootWindow(fEV) && (fWindowState->GetRootWindowCount(fEV,draft) == 1) &&
- (!(document->Exists(fEV, kODNULLID, draft, kODPosFirstAbove)));
-
- if (isOnlyTopDraftWindow &&
- ODDraftHasWriteAccess(fEV, draft) &&
- (draft->ChangedFromPrev(fEV) || ODIsUnsavedNewDocument(fEV, fSession, document)))
- {
- if (saveOptions == kAEYes)
- {
- ODSaveDocument(fEV, fSession, document);
- }
- else
- {
- ODReleaseObject(fEV, window); // balances AcquireODWindow above
-
- if (this->DoesUserCancelClose(document, saveOptions))
- return;
-
- window = fWindowState->AcquireODWindow(fEV,pwindow); // reacquire because user did not cancel close
- // NOTE: If the user SAVED the document inside the DoesUserCancelClose
- // call above for the first time, (thereby using StdFile), and to a
- // different volume, then DoesUserCancelClose did NOT reopen the document,
- // and pwindow is no longer a valid WindowPtr. Therefore, the windowstate
- // does not find it, and return kODNULL which causes the same code
- // execution as if the return statement above was executed.
- }
- }
-
- if (window)
- if (ODReleaseCloseWindow(fEV, fSession, window)) // balances AcquireODWindow above
- fDispatcher->Exit(fEV);
- }
-
- //------------------------------------------------------------------------------
- // RealShell::CloseDocument
- //
- // Result of true means that document was closed (or close was attempted).
- // Result of false means that the process was cancelled.
- //------------------------------------------------------------------------------
-
- ODBoolean RealShell::CloseDocument(ODDocument* document, DescType saveOptions)
- {
- ODDraft* draft = ODGetTempDraftFromOpenDocument(fEV, fSession, document);
- ODBoolean result = kODTrue;
-
- if (draft != kODNULL &&
- ODDraftHasWriteAccess(fEV, draft) &&
- (draft->ChangedFromPrev(fEV) || ODIsUnsavedNewDocument(fEV, fSession,
- document)))
- {
- if (this->DoesUserCancelClose(document, saveOptions))
- result = kODFalse;
- }
- if (result == kODTrue)
- {
- if (ODCloseDocument(fEV, fSession, document))
- fDispatcher->Exit(fEV);
- }
-
- return result;
- }
-
- //------------------------------------------------------------------------------
- // RealShell::DeleteDocument
- //------------------------------------------------------------------------------
-
- void RealShell::DeleteDocument(ODDocument* document)
- {
- // First, ask the user if they are sure they want to delete!
- if (!IsOptionKeyDown())
- {
- ArrowCursor();
-
- char fileName[256];
- ODGetDocumentFileName(fEV, document, &(fileName[0]));
- CToPascalString(fileName);
-
- ODSLong savedRefNum;
- BeginUsingLibraryResources(savedRefNum);
-
- ParamText(kODEmptyPString, (unsigned char const *)fileName,
- kODEmptyPString, kODEmptyPString);
-
- fWindowState->DeactivateFrontWindows(fEV);
-
- ODSShort btnClicked;
- TRY
- {
- DialogPtr askRevertDlg = kODNULL;
- askRevertDlg = ODGetNewDialog( fEV, kSHLDeleteDLOG, fSession, kODTrue );
- THROW_IF_NULL( askRevertDlg );
- ODUseCommandKeyStringsResource( kSHLDeleteDLOGCmdKeyStrs );
- ::ShowWindow( askRevertDlg );
- ::ModalDialog( GetODButtonKeyFilterProc(), &btnClicked );
- ::DisposeDialog( askRevertDlg );
- }
- CATCH_ALL
- {
- btnClicked = kSHLscCancel; // Cancel the delete
- }
- ENDTRY;
-
- fWindowState->ActivateFrontWindows(fEV);
-
- EndUsingLibraryResources(savedRefNum);
- if (!(kSHLscOK == btnClicked))
- return;
- }
-
- TempPlatformFile
- currentFile = GetPlatformFileFromContainer(fEV, document->GetContainer(fEV));
-
- ODSaveDocument(fEV, fSession, document);
- if (ODCloseDocument(fEV, fSession, document))
- fDispatcher->Exit(fEV);
-
- currentFile->MoveToTrash();
- }
-
- //-------------------------------------------------------------------------------------
- // Save
- //-------------------------------------------------------------------------------------
-
- ODBoolean RealShell::Save(ODDocument* document, ODBoolean isClosing, ODDescType saveOptions)
- {
- if (ODIsUnsavedNewDocument(fEV, fSession, document) && saveOptions == kAEAsk)
- {
- StandardFileReply reply;
- Str255 fileName;
- ODBoolean wasStationery;
-
- ODGetDocumentFileName(fEV, document, (char*)&(fileName[0]));
- CToPascalString((char*)fileName);
-
- Str255 msg;
- { CUsingLibraryResources r;
- GetIndString(msg, kSHLStrsID, kSHLStrIndDSaveAs);
- }
-
- TempPlatformFile
- currentFile = GetPlatformFileFromContainer(fEV, document->GetContainer(fEV));
- wasStationery = currentFile->IsStationery();
-
- // Need to rename file on disk briefly to avoid erroneous "Replace?" dialog
-
- // $$$$$ DOES NOT ACCOUNT FOR THE CASE WHERE THE filename+" " already exists !!!!!!
-
- FSSpec currentFSSpec = currentFile->GetFileSpec();
- if (currentFSSpec.name[0] < kODMaxFileNameSize)
- currentFSSpec.name[++currentFSSpec.name[0]] = 0x20;
- else
- --currentFSSpec.name[0];
-
- TRY
- currentFile->Rename(currentFSSpec.name);
- CATCH_ALL
- WARN("Unable to rename to avoid replace dialog. One replace dialog coming up!");
- ENDTRY
-
- // This would be cleaner, but not optimal
- // currentFile->UniquifyName(,,,,kRenameInPlace);
-
- ODDraft* draft = ODGetTempDraftFromOpenDocument(fEV, fSession, document);
- ODBoolean isStationery =
- this->AskUserWhereToPutIt(draft, fileName, msg, &reply );
-
- if (!reply.sfGood)
- {
- TRY
- currentFile->Rename(fileName);
- CATCH_ALL
- ENDTRY
- return kODFalse;
- }
-
- {
- // This assumes that the front window is the one being saved.
- // This might not be true for scripting, although it is right now
- // since we can only script the front window.
- TempODWindow window = fWindowState->AcquireFrontRootWindow(fEV);
- TempPlatformFile usersFile = ODGetFileIfRoot(fEV,
- window->GetRootFacet(fEV)->GetFrame(fEV));
- if (usersFile)
- usersFile->SetStationery(isStationery);
- // RESET INITED BIT OF FILE. THE FINDER HAS A BUG
- // WHERE IT WON'T UPDATE THE ICON IN THE FINDER IF ONLY THE
- // STATIONERY BIT IS CHANGED.
- if (wasStationery != isStationery
- && usersFile->IsEqualTo(currentFile))
- usersFile->UnsetFinderFlag(kHasBeenInited);
- }
-
- TempPlatformFile file = new PlatformFile();
- file->Specify(&reply.sfFile);
-
- if (file->IsEqualTo(currentFile))
- ; // do nothing, we'll save down below right ontop of the current document.
- else
- {
- if (reply.sfReplacing)
- {
- TRY
- file->Delete();
- CATCH_ALL
- THROW(kODErrCannotSaveAsOntoBusyDoc);
- ENDTRY;
- }
-
- if (reply.sfFile.vRefNum == currentFile->GetFileSpec().vRefNum)
- {
- currentFile->MoveRename(&(reply.sfFile), kODFalse);
- }
- else
- {
- if (!isClosing)
- this->ShowSaveDiffVolDialog();
-
- ODSaveDocument(fEV, fSession, document);
- ODBoolean wasLastDocument = ODCloseDocument(fEV, fSession, document);
- file->CopyFrom(currentFile);
- currentFile->Delete();
- if (!isClosing)
- {
- ODDraft* topdraft = ODOpenFileDocument(fEV, fSession, file, kODDPExclusiveWrite);
- document = topdraft->GetDocument(fEV);
- this->InstallShellPlugIns(topdraft);
-
- ODOpenDraft(fEV, fSession, topdraft);
- this->CloseSaveDiffVolDialog();
-
- ODReleaseObject(fEV, topdraft);
-
- fDispatcher = fSession->GetDispatcher(fEV);
- fWindowState = fSession->GetWindowState(fEV);
- fArbitrator = fSession->GetArbitrator( fEV );
- }
- else
- {
- if (wasLastDocument)
- fDispatcher->Exit(fEV);
- }
-
- LMSetSFSaveDisk(-(reply.sfFile.vRefNum));
- LMSetCurDirStore(reply.sfFile.parID);
- }
- }
- }
-
- ODSetIsTempDocument(fEV, ODGetTempDraftFromOpenDocument(fEV, fSession, document), kODFalse);
- ODSaveDocument(fEV, fSession, document);
- return kODTrue;
- } // RealShell::Save
-
- void RealShell::ShowSaveDiffVolDialog( )
- {
- if( !fSaveDiffVolDialog ) {
- CUsingLibraryResources r;
- fSaveDiffVolDialog = ::GetNewDialog(kSHLSaveDiffVolDialogID,kODNULL,(WindowPtr)-1L);
- ::ShowWindow(fSaveDiffVolDialog);
- ::DrawDialog(fSaveDiffVolDialog);
- }
- }
-
- void RealShell::CloseSaveDiffVolDialog( )
- {
- if( fSaveDiffVolDialog ) {
- CUsingLibraryResources r;
- ::DisposeDialog(fSaveDiffVolDialog);
- fSaveDiffVolDialog = kODNULL;
- }
- }
-
- //-------------------------------------------------------------------------------------
- // Save A Copy
- //-------------------------------------------------------------------------------------
-
- pascal void DrawSmallIcon(DialogPtr theDialog, short theItem)
- {
- short itemHit;
- Handle scratchHandle;
- Rect scratchRect;
-
- GetDialogItem(theDialog, theItem, &itemHit, &scratchHandle, &scratchRect);
-
- (void) PlotIconID (&scratchRect, atNone, ttNone,
- theItem == kSHLSaCDocumentIconItem ? kSHLSaCDocumentIconID : kSHLSaCStationeryIconID);
- }
-
- pascal short SaveCopyDlgHook(short item, DialogPtr theDialog, void *saveDataPtr)
- {
- short itemHit;
- Handle scratchHandle;
- Rect scratchRect;
- ODSShort translateItem = 0;
- ODSShort currentKindItem = 0;
-
- UserItemUPP drawSmallIconUPP = ((SaveCopyStruct*)saveDataPtr)->iconUPP;
-
- if ( ((WindowPeek)theDialog)->refCon == sfMainDialogRefCon )
- switch (item) {
- case sfHookFirstCall:
- GetDialogItem(theDialog, kSHLSaCDocumentIconItem, &itemHit, &scratchHandle, &scratchRect);
- SetDialogItem(theDialog, kSHLSaCDocumentIconItem, itemHit, (Handle) drawSmallIconUPP, &scratchRect);
-
- GetDialogItem(theDialog, kSHLSaCStationeryIconItem, &itemHit, &scratchHandle, &scratchRect);
- SetDialogItem(theDialog, kSHLSaCStationeryIconItem, itemHit, (Handle) drawSmallIconUPP, &scratchRect);
-
- GetDialogItem(theDialog, kSHLSaCDocumentRadioBtn, &itemHit, &scratchHandle, &scratchRect);
- SetControlValue( (ControlHandle) scratchHandle, !((SaveCopyStruct*)saveDataPtr)->makeStationery);
-
- GetDialogItem(theDialog, kSHLSaCStationeryRadioBtn, &itemHit, &scratchHandle, &scratchRect);
- SetControlValue( (ControlHandle) scratchHandle, ((SaveCopyStruct*)saveDataPtr)->makeStationery);
-
- GetDialogItem(theDialog, kSHLSaCKindPopupItem, &itemHit, &scratchHandle, &scratchRect);
- MenuHandle kindMenu = GetMenu(kSHLSaCKindPopupMenu);
- THROW_IF_NULL(kindMenu);
-
- InitKindsPopup(((SaveCopyStruct*)saveDataPtr)->kindList,
- ((SaveCopyStruct*)saveDataPtr)->partKind,
- (ControlHandle)scratchHandle,
- ¤tKindItem, kindMenu, &translateItem,
- ((SaveCopyStruct*)saveDataPtr)->session);
- break;
-
- case kSHLSaCDocumentRadioBtn :
- GetDialogItem(theDialog, kSHLSaCDocumentRadioBtn, &itemHit, &scratchHandle, &scratchRect);
- SetControlValue( (ControlHandle) scratchHandle, 1);
- GetDialogItem(theDialog, kSHLSaCStationeryRadioBtn, &itemHit, &scratchHandle, &scratchRect);
- SetControlValue( (ControlHandle) scratchHandle, 0);
-
- break;
-
- case kSHLSaCStationeryRadioBtn :
- GetDialogItem(theDialog, kSHLSaCDocumentRadioBtn, &itemHit, &scratchHandle, &scratchRect);
- SetControlValue( (ControlHandle) scratchHandle, 0);
- GetDialogItem(theDialog, kSHLSaCStationeryRadioBtn, &itemHit, &scratchHandle, &scratchRect);
- SetControlValue( (ControlHandle) scratchHandle, 1);
-
- break;
-
- case sfHookLastCall :
- /* check value of radio buttons and save accordingly */
- GetDialogItem(theDialog, kSHLSaCStationeryRadioBtn, &itemHit, &scratchHandle, &scratchRect);
- ((SaveCopyStruct*)saveDataPtr)->makeStationery = GetControlValue( (ControlHandle) scratchHandle);
- ((SaveCopyStruct*)saveDataPtr)->changeKind = kODNULL;
- GetDialogItem(theDialog, kSHLSaCKindPopupItem, &itemHit, &scratchHandle, &scratchRect);
- ODSShort kindItem = (ODSShort) GetControlValue((ControlHandle)scratchHandle);
- if (kindItem != currentKindItem)
- {
- ODType newKind = GetThisKindFromList(kindItem,
- ((SaveCopyStruct*)saveDataPtr)->kindList);
- ((SaveCopyStruct*)saveDataPtr)->changeKind = newKind;
- }
-
- break;
- }
-
- return (item);
- }
-
- ODBoolean RealShell::AskUserWhereToPutIt( ODDraft* whichDraft, Str255 defaultName,
- Str255 msg, StandardFileReply* reply )
- {
- Point pt;
- SetPt(&pt, 0, 0);
-
- ODBoolean makeStationery;
-
- ODSLong savedRefNum;
- // Setup fSaveCopyData fields for custom put file
- fSaveCopyData = new SaveCopyStruct;
-
- fSaveCopyData->session = this->GetSession();
- TempODPart rootPart = ODAcquireRootPartOfDraft(fEV, whichDraft);
-
- ODContainer* container = whichDraft->GetDocument(fEV)->GetContainer(fEV);
- TempPlatformFile file = GetPlatformFileFromContainer(fEV, container);
- fSaveCopyData->makeStationery = file->IsStationery();
- // fSaveCopyData->makeStationery = kODFalse; // always default to saving a document
-
-
- fSaveCopyData->partKind = ODGetKind(fEV, rootPart );
- fSaveCopyData->kindList =
- fSession->GetStorageSystem(fEV)->CreateTypeList(fEV, kODNULL);
-
- // get StorageUnit kinds
- ContentValueTypes(rootPart->GetStorageUnit(fEV), fSaveCopyData->kindList);
-
- // get all kinds supported by this editor
- ODNameSpaceManager* nsm = fSaveCopyData->session->GetNameSpaceManager(fEV);
- ODEditor editorID = GetCurrentEditorForPart(rootPart);
- GetAllKindsForEditor(nsm, fSaveCopyData->kindList, editorID);
- ODDisposePtr(editorID);
-
- BeginUsingLibraryResources(savedRefNum);
- fSaveCopyData->iconUPP = NewUserItemProc(DrawSmallIcon);
- DlgHookYDUPP saveACopyUPP = NewDlgHookYDProc(SaveCopyDlgHook);
-
- fWindowState->DeactivateFrontWindows(fEV);
-
- {
- TempODMenuBar currentMenuBar = fWindowState->AcquireCurrentMenuBar(fEV);
- ODDialogBegin(fEV, fSession, currentMenuBar, kODNULL);
- CustomPutFile(msg, defaultName, reply,
- kSHLSaveCopyDlgID, pt, saveACopyUPP, kODNULL, kODNULL , kODNULL, fSaveCopyData);
- ODDialogEnd();
- }
-
- fWindowState->ActivateFrontWindows(fEV);
-
- DisposeRoutineDescriptor(saveACopyUPP);
- DisposeRoutineDescriptor(fSaveCopyData->iconUPP);
- EndUsingLibraryResources(savedRefNum);
-
- makeStationery = fSaveCopyData->makeStationery;
-
- ODDisposePtr( fSaveCopyData->partKind );
- ODDeleteObject( fSaveCopyData->kindList );
- ODDeleteObject( fSaveCopyData );
-
- return makeStationery;
- }
-
- void RealShell::SaveACopy(ODDraft* draft)
- {
- // save a copy of the topmost draft into a new container
- StandardFileReply reply;
-
- Str255 msg;
-
- ODDocument* document = draft->GetDocument(fEV);
-
- Str255 fileName;
- ODGetDocumentFileName(fEV, document, (char*)&(fileName[0]));
- CToPascalString((char*)fileName);
-
- Str255 defaultName;
-
- // HI$ #1247070: should we append " Draft <n>" if the user happens to be saving
- // a copy of a draft?
-
- { CUsingLibraryResources r;
- GetIndString(msg, kSHLStrsID, kSHLStrIndDSaveACopy);
- ReplaceIntoString(kSHLCopyDefaultStrID, fileName, kODEmptyPString, defaultName);
- }
- if (defaultName[0] > kODMaxFileNameSize)
- ClipStringToBytes( defaultName, kODMaxFileNameSize, smCurrentScript );
-
- ODBoolean isStationery =
- this->AskUserWhereToPutIt(draft, defaultName, msg, &reply );
- if (!reply.sfGood)
- return;
-
- TempPlatformFile file = new PlatformFile();
- file->Specify(&reply.sfFile);
-
- TempPlatformFile
- currentFile = GetPlatformFileFromContainer(fEV, document->GetContainer(fEV));
-
- if (reply.sfReplacing)
- {
- ODBoolean isEqual = file->IsEqualTo(currentFile);
-
- if (isEqual != kODFalse)
- {
- THROW(kODErrCannotSaveACopyOntoCurrentDoc);
- }
-
- TRY
- file->Delete();
- CATCH_ALL
- THROW(kODErrCannotSaveACopyOntoBusyDoc);
- ENDTRY;
- }
-
- ODSaveACopyOfDraft(fEV, fSession, draft, file);
- file->SetStationery(isStationery);
- CopyResources(currentFile, file); // copy the resource over to the new copy
- }
-
-
- void
- RealShell::CloseAllDocs( DescType /* saveOptions */ ) // will be handled by
- // quit handler
- {
- // CyberDog wants to intercept the quit apple event, so send ourselves one.
-
- ProcessSerialNumber psn = {0, kCurrentProcess};
- OSErr error = noErr;
- AEAddressDesc address = {typeNull, NULL};
- AppleEvent message = {typeNull, NULL};
- AppleEvent reply = {typeNull, NULL};
-
- ODVolatile(error);
-
- TRY
- THROW_IF_ERROR(AECreateDesc(typeProcessSerialNumber, (Ptr)&psn, sizeof(psn),
- &address));
- THROW_IF_ERROR(AECreateAppleEvent(kCoreEventClass, kAEQuitApplication,
- &address, kAutoGenerateReturnID, kAnyTransactionID,
- &message));
- THROW_IF_ERROR(AESend(&message, &reply,
- kAENoReply + kAECanInteract,
- kAENormalPriority, kAEDefaultTimeout,
- (AEIdleUPP)kODNULL, (AEFilterUPP)kODNULL));
- CATCH_ALL
- error = ErrorCode();
- ENDTRY
-
- AEDisposeDesc(&address);
- AEDisposeDesc(&message);
- AEDisposeDesc(&reply);
-
- THROW_IF_ERROR(error);
-
- #if 0
- for( TempODWindowIterator wi(fEV,fSession->GetWindowState(fEV)); wi; ++wi ) {
- ODDocument *document = ODGetDraftOfWindow(fEV,wi)->GetDocument(fEV);
- if( ! this->CloseDocument(document, saveOptions) )
- return; /* user canceled */
- }
- // CloseDocument method will tell dispatcher to exit when last doc closes.
- #endif /* 0 */
- }
-
-
- //-------------------------------------------------------------------------------------
- // Revert
- //-------------------------------------------------------------------------------------
-
-
- void RealShell::Revert(ODDocument* document)
- {
- if (this->DoesUserOKRevert(document))
- {
- ODRevertDocument(fEV, fSession, document);
- }
- }
-
- ODBoolean RealShell::DoesUserOKRevert(ODDocument* document)
- {
- // asks user "Revert to the last saved version?"
-
- ArrowCursor();
-
- char fileName[256];
- ODGetDocumentFileName(fEV, document, &(fileName[0]));
- CToPascalString(fileName);
-
- ODSLong savedRefNum;
- BeginUsingLibraryResources(savedRefNum);
-
- ParamText(kODEmptyPString, (unsigned char const *)fileName,
- kODEmptyPString, kODEmptyPString);
-
- fWindowState->DeactivateFrontWindows(fEV);
-
- ODSShort btnClicked;
- TRY
- {
- DialogPtr askRevertDlg = kODNULL;
- askRevertDlg = ODGetNewDialog( fEV, kSHLsvRevert, fSession, kODTrue );
- THROW_IF_NULL( askRevertDlg );
- ODUseCommandKeyStringsResource( kSHLsvRevertCmdKeyStrs );
- ::ShowWindow( askRevertDlg );
- ::ModalDialog( GetODButtonKeyFilterProc(), &btnClicked );
- ::DisposeDialog( askRevertDlg );
- }
- CATCH_ALL
- {
- btnClicked = kSHLscCancel; // Cancel the revert
- }
- ENDTRY;
-
- fWindowState->ActivateFrontWindows(fEV);
-
- EndUsingLibraryResources(savedRefNum);;
- return kSHLscOK == btnClicked;
- }
-
-
- //-------------------------------------------------------------------------------------
- // Drafts
- //-------------------------------------------------------------------------------------
- #ifdef _USE_DIALOGS_LIB_
- #ifdef __cplusplus
- extern "C" {
- #endif
- typedef ODError (*DraftWindowEntry)( Environment* ev, ODSession* session,
- ODWindowState* winState, ODDocument* document );
- #ifdef __cplusplus
- }
- #endif
-
- OSErr LoadODSharedLibrary( Str63 libName, Str255 entryName,
- CFragConnectionID* connID, void** entryPoint );
- void UnloadODSharedLibrary( CFragConnectionID* connID );
-
- #endif
- void RealShell::Drafts(ODDocument* document)
- {
- #ifdef _USE_DIALOGS_LIB_
- DraftWindowEntry dwi = kODNULL;
- CFragConnectionID connID ;
- THROW_IF_ERROR( LoadODSharedLibrary( "\pDialogsLib",
- "\pDraftWindowEntry", &connID, (void**)&dwi ) );
- THROW_IF_ERROR( (*dwi)( fEV, fSession, fWindowState, document ) );
- UnloadODSharedLibrary( &connID );
- return;
- #else
- ODDraft* topDraft = ODGetTempDraftFromOpenDocument(fEV, fSession, document);
- if (topDraft)
- topDraft->Acquire(fEV);
- else
- topDraft = document->AcquireDraft(fEV,kODDPReadOnly,0,kODNULL,kODPosTop,kODFalse);
-
- DraftWindow* d = new DraftWindow;
- DraftWinAction dWinAction = kDraftWinNone;
- ODDraft* curDraft = kODNULL;
- d->InitDraftWindow(fEV, topDraft);
-
- fWindowState->DeactivateFrontWindows(fEV);
- ArrowCursor();
- do {
- dWinAction = d->Drafts(fEV, curDraft, dWinAction, ODDraftHasWriteAccess(fEV, topDraft));
- switch (dWinAction) {
- case kDraftWinCreate:
- WASSERT(ODDraftHasWriteAccess(fEV, topDraft));
- fWindowState->ActivateFrontWindows(fEV);
- d->DraftSaved(fEV, topDraft);
- ODSaveDocument(fEV, fSession, document);
- ODCloseDraft(fEV, fSession, topDraft);
- #ifdef ODDebug
- ODULong topDraftRefCount = topDraft->GetRefCount(fEV);
- WASSERT(topDraftRefCount == 2);
- #endif
- topDraft->Release(fEV); // to balance the CreateDraft when the document was opened
- topDraft = document->CreateDraft(fEV, topDraft, kODTrue);
- // This CreateDraft call is doing two things with refcounts.
- // First, it is releasing topDraft which balances the Acquire at the top of
- // this function.
- // Second, it is creating a new temp draft, which puts us in the same
- // state as we were before the above topDraft->Release, except
- // for the need to Reacquire the topDraft as was done at the top of this
- // function which we do in the next statement.
- topDraft->Acquire(fEV);
-
- ODTempDraftCreated(fEV, fSession, document, topDraft);
- curDraft = topDraft;
-
- {
- TempODStorageUnit su = topDraft->AcquireDraftProperties(fEV);
- ODResetDateModByInfo(fEV, su);
- }
-
- d->InitDraftWindow(fEV, topDraft);
- ODOpenDraft(fEV, fSession, topDraft);
- ODSaveDocument(fEV, fSession, document);
- fWindowState->DeactivateFrontWindows(fEV);
-
- break;
- case kDraftWinDelete:
- ODDraft* selDraft = d->GetSelectedDraft();
-
- ODCloseDraft(fEV, fSession, selDraft);
- ODReleaseObject( fEV, selDraft ); // -- TÇ: was acquired in draftswindow
-
- d->DeleteSelectedDraft(fEV, fSession);
- break;
- }
- } while (dWinAction == kDraftWinDelete);
-
- fWindowState->ActivateFrontWindows(fEV);
-
- if (dWinAction == kDraftWinOpen)
- {
- // open selected Drafts as additional root windows within this process
- // if a particular draft already has a window, bring it to front, don't create a new one
- ODDraft* selDraft = d->GetSelectedDraft();
- WASSERT(selDraft);
-
- ODOpenDraft(fEV, fSession, selDraft);
- }
- ODDeleteObject(d);
- ODReleaseObject( fEV, topDraft ); // balances Acquire & AcquireDraft at beginning.
-
- if ( dWinAction == kDraftWinLowMemAbort )
- THROW( kODErrOutOfMemory );
- #endif
- }
-
- //-------------------------------------------------------------------------------------
- // Info
- //-------------------------------------------------------------------------------------
-
-
- void RealShell::DocumentInfo(ODDocument* document)
- {
- ODUnused(document);
-
- ODDocumentInfo(fEV, fSession);
- }
-
- /*
- // Default implementation for active parts which do nothing. Keep this code -TÇ.
- void RealShell::PartInfo()
- {
- ArrowCursor();
- ODTypeToken selectionFocus = fSession->Tokenize(fEV, kODSelectionFocus);
- TempODFrame activeFrame = fSession->GetArbitrator(fEV)->AcquireFocusOwner(fEV, selectionFocus);
- ODFrameFacetIterator* facets = activeFrame->CreateFacetIterator(fEV);
- fSession->GetInfo(fEV)->ShowPartFrameInfo(fEV, facets->First(fEV),
- this->HasWriteAccess());
- ODDeleteObject(facets);
- }
- */
-
- //-------------------------------------------------------------------------------------
- // Error Handling
- //-------------------------------------------------------------------------------------
-
- void RealShell::ExceptionAlert(ODError exceptionCode, const char message[])
- {
- Str255 errStr;
-
- gODDelayBentoFatalError = gODSuppressBentoFatalError = kODFalse;
- if ( gODBentoFatalErrorHasOccurred )
- ODBentoFatalError(/*allowSuppress*/ kODFalse);
-
- // Errors not to display:
- if( exceptionCode == kODNoError || exceptionCode == kODErrAlreadyNotified
- || exceptionCode == userCanceledErr )
- return;
-
- // If interaction is allowed, notify user until process is activated:
- if( AEInteractWithUser(kNoTimeOut,kODNULL,kODNULL) != noErr )
- return;
-
- TRY{
-
- CUsingLibraryResources r;
-
- ODBoolean lowMem = ! this->CheckFreeMemory();
-
- TRY{
- if (fWindowState)
- fWindowState->DeactivateFrontWindows(fEV);
- }CATCH_ALL{
- WARN("Error %d deactivating front windows",ErrorCode());
- // don't reraise
- }ENDTRY
-
- LookupErrString(exceptionCode, kODErrUserID, errStr);
- if ( fFailedPlugInName[0] != 0 )
- {
- ReplaceIntoString( kSHLPlugInErrorStrID, fFailedPlugInName, errStr, errStr);
- fFailedPlugInName[0] = 0;
- }
-
- #if ODDebug
- ParamText(errStr, "\pOption-click OK for more…", kODEmptyPString, kODEmptyPString);
- // NOTE: This hard coded string is ok because it is for debugging only. -TC
- #else
- ParamText(errStr, kODEmptyPString, kODEmptyPString, kODEmptyPString);
- #endif
-
- // Do not use a filter-proc if low on memory since it calls back to OpenDoc!
- ModalFilterUPP filter = lowMem ?kODNULL :GetODButtonKeyFilterProc();
-
-
- // Shazam! Show the alert:
- ShowAlert(fEV, kSHLphGenError, filter, fSession);
-
- TRY{
- if (IsOptionKeyDown())
- {
- Str255 debugStrString;
- debugStrString[0] = 0;
-
- GetIndString(debugStrString, kSHLStrsID, kSHLStrIndDException);
-
- Str255 tempString;
-
- NumToString(exceptionCode, tempString);
- if (debugStrString[0] + tempString[0] <= 255)
- ConcatPascalStrings(debugStrString, tempString);
-
- LookupErrString(exceptionCode, kODErrSupportID, errStr);
-
- char msg[256];
- if( message ) {
- strncpy(msg,message,255);
- msg[255] = 0;
- c2pstr(msg);
- } else
- msg[0] = 0;
-
- ParamText(errStr, debugStrString, (StringPtr)msg, kODEmptyPString);
- ShowAlert(fEV, kSHLphGenError, filter, fSession);
- }
- }CATCH_ALL{
- WARN("Error %d handling opt key down",ErrorCode());
- // don't reraise
- }ENDTRY
-
- #ifdef SHLTestErrorDialogUsage
- SHLDebugStr("\pPostErrorDialog HeapInfo…");
- HeapInfo();
- #endif
-
- TRY{
- if (fWindowState)
- fWindowState->ActivateFrontWindows(fEV);
- }CATCH_ALL{
- WARN("Error %d re-activating front windows",ErrorCode());
- // don't reraise
- }ENDTRY
-
- ResetAlertStage();
-
- }CATCH_ALL{
- SysBeep(3);
- WARN("Error %d thrown by exception alert",ErrorCode());
- // Eat exception, don't reraise
- }ENDTRY
-
- gODDelayBentoFatalError = gODSuppressBentoFatalError = kODFalse;
- if ( gODBentoFatalErrorHasOccurred )
- ODBentoFatalError(/*allowSuppress*/ kODFalse);
- }
-
- //----------------------------------------------------------------------------------------
- // SearchErrTable: Private function
- //----------------------------------------------------------------------------------------
-
- ODBoolean RealShell::SearchErrTable(ODError value,
- ODResNumber resourceID,
- Str255 str)
- {
- ErrRecordHandle table;
-
- str[0] = 0;
- ODSLong savedRefNum;
- BeginUsingLibraryResources(savedRefNum);
- table = (ErrRecordHandle)GetResource('errs', resourceID);
- DetachResource((Handle)table);
- EndUsingLibraryResources(savedRefNum);
-
- if (table)
- {
- short lenTab;
- ODResNumber strID = 0;
- SignedByte savedState = HGetState((Handle)table);
- HLock((Handle)table);
-
- ErrRecordPointer pEntry = *table;
-
- lenTab = (short)(GetHandleSize((Handle)table) / sizeof(ErrRecord));
- for (short i = 1; i <= lenTab; ++i, ++pEntry)
- {
- if (pEntry->lowErr == 0)
- strID = (ODResNumber)(pEntry->index); // WARNING: assigning an ODULong to a short
- else if ((pEntry->lowErr <= value) && (value <= pEntry->highErr))
- {
- if (pEntry->index > 0)
- {
- ODSLong savedRefNum;
- BeginUsingLibraryResources(savedRefNum);
- GetIndString(str, strID, (ODResNumber)(pEntry->index)); // WARNING: passing in an ODULong as a short
- EndUsingLibraryResources(savedRefNum);;
- }
- return kODTrue;
- }
- }
- HSetState((Handle)table, savedState);
- }
- return kODFalse;
- } // SearchErrTable
-
- //----------------------------------------------------------------------------------------
- // LookupErrString:
- //----------------------------------------------------------------------------------------
-
- ODBoolean RealShell::LookupErrString(ODError value,
- ODResNumber resourceID,
- Str255 str)
- {
- if (SearchErrTable(value, 0/*errAppTable*/ + resourceID, str))
- return kODTrue;
- else
- return SearchErrTable(value, resourceID, str);
- } // LookupErrString
-
- //----------------------------------------------------------------------------------------
- // CreateDefaultIText:
- //
- // <eeh> this might be more useful in IText.cpp or whatever it's called.
- //----------------------------------------------------------------------------------------
-
- static ODIText* CreateDefaultIText(StringPtr text)
- {
- ODScriptCode script = FontToScript( GetSysFont() );;
- ODLangCode lang = GetScriptVariable(script, smScriptLang);
- return CreateITextPString( script, lang, text);
- }
-
- /*********************************************************************************
- SendFinderODOCEvent
- Temporary function that should be merged with Jens's CreateFinderRevealEvent in
- WinPopM.cpp (UI subsystem). Or perhaps we needn't bother, since this is just
- a workaround anyway.
- *********************************************************************************/
-
- static OSErr SendFinderODOCEvent( const FSSpec *fileToOpen )
- {
- const DescType kFinderSignature = 'MACS';
-
- OSErr err;
- OSType finderSignature = kFinderSignature;
- AliasHandle alias = NULL;
- AEDesc target = NULL_DESCRIPTOR_DEFINITION;
- AEDescList list = NULL_DESCRIPTOR_DEFINITION;
-
- AppleEvent openEvent = NULL_DESCRIPTOR_DEFINITION;
-
- err= AECreateDesc(typeApplSignature,&finderSignature,sizeof(OSType), &target);
- if( err ) goto exit;
- err= AECreateAppleEvent( kCoreEventClass, kAEOpenDocuments, &target,
- kAutoGenerateReturnID, kAnyTransactionID, &openEvent );
- if( err ) goto exit;
- // AEDisposeDesc(&target);
- err= NewAliasMinimal( fileToOpen, &alias );
- if( err ) goto exit;
-
- err= AECreateList(NULL,0,false, &list);
- if( err ) goto exit;
- err= AEPutPtr(&list,1,typeAlias,*alias,GetHandleSize((Handle)alias));
- if( err ) goto exit;
-
- err= AEPutParamDesc(&openEvent, keyDirectObject, &list);
- if( err ) goto exit;
-
- err = AESend( &openEvent, kODNULL,
- kAENoReply|kAEAlwaysInteract|kAECanSwitchLayer,
- kAENormalPriority, kNoTimeOut, kODNULL, kODNULL );
-
- if (err == connectionInvalid)
- FinderNotRunning();
-
- exit:
- AEDisposeDesc(&target);
- AEDisposeDesc(&list);
- if( alias ) DisposeHandle((Handle)alias);
- // if( err )
- AEDisposeDesc(&openEvent);
-
- return err;
- }
-
- //------------------------------------------------------------------------------
- // FinderNotRunning
- //------------------------------------------------------------------------------
-
- void FinderNotRunning()
- {
- StopAlert(kODAlertShellFinderNotRunning, (ModalFilterUPP)NULL);
- }
-
- //------------------------------------------------------------------------------
- // ReportErrorGeneric
- //------------------------------------------------------------------------------
-
- void ReportErrorGeneric(StringPtr errorString)
- {
- ReportErrorSimple(errorString);
- }
-
-